Re: [Mesa-dev] [RFC] loader: Automatic PRIME detection

2017-01-03 Thread Axel Davy

On 02/01/2017 15:32, Thierry Reding wrote:

On Tue, Dec 27, 2016 at 01:57:21PM +0100, Axel Davy wrote:

Hi Thierry,

Could you explain why in this situation default_fd would be a non-renderable
device node ?

This is preparatory work to allow drivers for split display/render
setups to be tied together within Mesa. If you want accelerated
rendering on those setups, you currently need to patch applications so
that they can deal with two separate devices (patches exist to allow
this for Weston and kmscube, and possibly others).

In order to avoid having to patch applications, the renderonly (the name
is slightly confusing) drivers (Christian Gmeiner sent out patches a few
weeks ago) open two devices internally and contain some magic to share
buffers between the two devices.

So the typical use-case would be that you have two separate DRM devices,
one representing the scanout device and another representing the GPU. In
most cases the scanout device will be display-only, so it will have a
/dev/dri/cardX node, but no corresponding /dev/dri/renderDY node. On the
other hand the GPU will have a "dummy" /dev/dri/cardX node that doesn't
expose any outputs and a corresponding /dev/dri/renderDY node that is
used for rendering.

A bare-metal application (kmscube, Weston, ...) will have to find a node
to perform a modeset with, so it will have to find a /dev/dri/cardX node
which exposes one or more outputs. That will be the scanout device node.
But given that there's no render node there's no way to accelerate using
that device.

Composite drivers will bind to the scanout device node and find a render
node for the GPU (these are usually ARM SoCs, so it's fairly easy to
find the correct render node) and bind the GPU driver to that node. Then
the GPU driver will export buffers used for scanout and have the scanout
driver import them. That way the application can transparently use those
buffers for DRM/KMS.


In my understanding, for X11 DRI3 the Xserver is supposed to give you a
renderable device node,
and for Wayland, the device path advertised is the one used by the server
for compositing.

Both X11 and Wayland will try to use the device used by the server for
compositing. In both cases they will receive the /dev/dri/cardX device
node for the scanout device.

Effectively X11 and Wayland will call back into the scanout driver for
acceleration. However with a minimal renderonly driver that's not going
to work. I had posted a complete wrapper driver a long time ago which I
think could be improved to allow even this use-case to work, but I got
significant pushback.

Anyway, both X11 and Wayland use the loader_get_user_preferred_fd()
function that this patch modifies to allow overriding the final file
descriptor to use. Currently the only way to override is by providing
the DRI_PRIME environment variable or by setting up a dri.conf
configuration file.

loader_get_user_preferred_fd() returns a file descriptor (same as the
default_fd by default, or the one referring to the DRI_PRIME node) and a
flag that specifies whether or not the devices are the same. This is
used in order to determine if DMA-BUF or FLINK should be used to share
buffers.

X11 has special code paths to deal with the PRIME use-case involving an
extra blit, which is somewhat unfortunate because on many devices that's
not going to be necessary.

For Wayland the EGL platform code checks for availability of a render
node to determine whether or not DMA-BUF should be used. That breaks for
this particular case as well because we do have a cardX node without a
corresponding renderDY node.

I suspect that with a full wrapper driver this could be solved more
nicely, including avoiding the extra blit in X11 DRI3. However it's a
lot more code to maintain than piggy-backing on top of PRIME support,
and a lot more complicated to get right (and more potential for breaking
existing use-cases).

Thierry



From what you say, I understand the following, please correct if wrong:

Tthe issue is that you need some special format/placement in order to 
display on the screen.


A patch serie was proposed to handle that with some specific handling 
long ago, but received bad comments.


Because a linear buffer is ok to display, you want to force the 
"different device is rendering" path to enforce a copy to a linear 
buffer before presentation.


In the proposed scheme, X11 DRI3 open returns an fd of the device used 
for display (but which cannot render) and Wayland gives the path of the 
device used for display but which cannot be used for rendering.



This seems something that should really be discussed with the devs of 
#xorg-devel and #wayland.



My opinion is that is feels contrary to the spirit of X11 DRI3 to give 
an unusable device fd, and of Wayland to give the path of the device 
used for display by the server instead of the device the server uses for 
rendering.


What you seem to want is some sort of constraints 
format/placement/tiling on the buffers shared with the 

Re: [Mesa-dev] [RFC] loader: Automatic PRIME detection

2017-01-02 Thread Thierry Reding
On Tue, Dec 27, 2016 at 01:57:21PM +0100, Axel Davy wrote:
> Hi Thierry,
> 
> Could you explain why in this situation default_fd would be a non-renderable
> device node ?

This is preparatory work to allow drivers for split display/render
setups to be tied together within Mesa. If you want accelerated
rendering on those setups, you currently need to patch applications so
that they can deal with two separate devices (patches exist to allow
this for Weston and kmscube, and possibly others).

In order to avoid having to patch applications, the renderonly (the name
is slightly confusing) drivers (Christian Gmeiner sent out patches a few
weeks ago) open two devices internally and contain some magic to share
buffers between the two devices.

So the typical use-case would be that you have two separate DRM devices,
one representing the scanout device and another representing the GPU. In
most cases the scanout device will be display-only, so it will have a
/dev/dri/cardX node, but no corresponding /dev/dri/renderDY node. On the
other hand the GPU will have a "dummy" /dev/dri/cardX node that doesn't
expose any outputs and a corresponding /dev/dri/renderDY node that is
used for rendering.

A bare-metal application (kmscube, Weston, ...) will have to find a node
to perform a modeset with, so it will have to find a /dev/dri/cardX node
which exposes one or more outputs. That will be the scanout device node.
But given that there's no render node there's no way to accelerate using
that device.

Composite drivers will bind to the scanout device node and find a render
node for the GPU (these are usually ARM SoCs, so it's fairly easy to
find the correct render node) and bind the GPU driver to that node. Then
the GPU driver will export buffers used for scanout and have the scanout
driver import them. That way the application can transparently use those
buffers for DRM/KMS.

> In my understanding, for X11 DRI3 the Xserver is supposed to give you a
> renderable device node,
> and for Wayland, the device path advertised is the one used by the server
> for compositing.

Both X11 and Wayland will try to use the device used by the server for
compositing. In both cases they will receive the /dev/dri/cardX device
node for the scanout device.

Effectively X11 and Wayland will call back into the scanout driver for
acceleration. However with a minimal renderonly driver that's not going
to work. I had posted a complete wrapper driver a long time ago which I
think could be improved to allow even this use-case to work, but I got
significant pushback.

Anyway, both X11 and Wayland use the loader_get_user_preferred_fd()
function that this patch modifies to allow overriding the final file
descriptor to use. Currently the only way to override is by providing
the DRI_PRIME environment variable or by setting up a dri.conf
configuration file.

loader_get_user_preferred_fd() returns a file descriptor (same as the
default_fd by default, or the one referring to the DRI_PRIME node) and a
flag that specifies whether or not the devices are the same. This is
used in order to determine if DMA-BUF or FLINK should be used to share
buffers.

X11 has special code paths to deal with the PRIME use-case involving an
extra blit, which is somewhat unfortunate because on many devices that's
not going to be necessary.

For Wayland the EGL platform code checks for availability of a render
node to determine whether or not DMA-BUF should be used. That breaks for
this particular case as well because we do have a cardX node without a
corresponding renderDY node.

I suspect that with a full wrapper driver this could be solved more
nicely, including avoiding the extra blit in X11 DRI3. However it's a
lot more code to maintain than piggy-backing on top of PRIME support,
and a lot more complicated to get right (and more potential for breaking
existing use-cases).

Thierry

> On 23/12/2016 21:36, Thierry Reding wrote:
> > From: Thierry Reding 
> > 
> > If a device doesn't support rendering and support for PRIME isn't
> > enabled via the DRI_PRIME environment variable or dri.conf, attempt to
> > find a render node which can be used to offload rendering.
> > 
> > Signed-off-by: Thierry Reding 
> > ---
> > Along with platform and host1x bus support in the loader, this is the
> > final piece of the puzzle to automatically allow split scanout/render
> > devices to work with Wayland compositors and the X.Org server.
> > 
> > Note that this requires that the Wayland compositor and X.Org server
> > are accelerated with a DRI driver to make sure that the default file
> > descriptor is properly set up.
> > 
> >   src/loader/loader.c | 71 
> > ++---
> >   1 file changed, 67 insertions(+), 4 deletions(-)
> > 
> > diff --git a/src/loader/loader.c b/src/loader/loader.c
> > index 505c33133be6..6384432970f2 100644
> > --- a/src/loader/loader.c
> > +++ b/src/loader/loader.c
> > @@ -108,6 +108,71 @@ 

Re: [Mesa-dev] [RFC] loader: Automatic PRIME detection

2016-12-27 Thread Axel Davy

Hi Thierry,

Could you explain why in this situation default_fd would be a 
non-renderable device node ?


In my understanding, for X11 DRI3 the Xserver is supposed to give you a 
renderable device node,
and for Wayland, the device path advertised is the one used by the 
server for compositing.


Yours,

Axel Davy

On 23/12/2016 21:36, Thierry Reding wrote:

From: Thierry Reding 

If a device doesn't support rendering and support for PRIME isn't
enabled via the DRI_PRIME environment variable or dri.conf, attempt to
find a render node which can be used to offload rendering.

Signed-off-by: Thierry Reding 
---
Along with platform and host1x bus support in the loader, this is the
final piece of the puzzle to automatically allow split scanout/render
devices to work with Wayland compositors and the X.Org server.

Note that this requires that the Wayland compositor and X.Org server
are accelerated with a DRI driver to make sure that the default file
descriptor is properly set up.

  src/loader/loader.c | 71 ++---
  1 file changed, 67 insertions(+), 4 deletions(-)

diff --git a/src/loader/loader.c b/src/loader/loader.c
index 505c33133be6..6384432970f2 100644
--- a/src/loader/loader.c
+++ b/src/loader/loader.c
@@ -108,6 +108,71 @@ static char *loader_get_dri_config_device_id(void)
  }
  #endif
  
+/*

+ * For all devices that do not support rendering, try to find a different
+ * device that will.
+ *
+ * Note that the absence of a render node doesn't technically imply that
+ * the device can't render, but in practice this should work out fine.
+ */
+static int drm_detect_prime_fd(int default_fd, int *different_device)
+{
+   int err, fd = -ENODEV;
+   drmDevicePtr device;
+
+   err = drmGetDevice(default_fd, );
+   if (err < 0)
+  goto err;
+
+   if ((device->available_nodes & (1 << DRM_NODE_RENDER)) == 0) {
+  unsigned int num_devices, i;
+  drmDevicePtr *devices;
+
+  err = drmGetDevices(NULL, 0);
+  if (err < 0)
+ goto err;
+
+  num_devices = err;
+
+  devices = calloc(num_devices, sizeof(drmDevicePtr));
+  if (!devices)
+ goto err;
+
+  err = drmGetDevices(devices, num_devices);
+  if (err < 0) {
+ free(devices);
+ goto err;
+  }
+
+  num_devices = err;
+
+  for (i = 0; i < num_devices; i++) {
+ if (devices[i]->available_nodes & (1 << DRM_NODE_RENDER)) {
+fd = loader_open_device(devices[i]->nodes[DRM_NODE_RENDER]);
+if (fd < 0) {
+   fd = -errno;
+   continue;
+}
+
+close(default_fd);
+break;
+ }
+  }
+
+  drmFreeDevices(devices, num_devices);
+  free(devices);
+   }
+
+err:
+   if (fd < 0) {
+  *different_device = 0;
+  return default_fd;
+   }
+
+   *different_device = 1;
+   return fd;
+}
+
  static char *drm_construct_id_path_tag(drmDevicePtr device)
  {
  /* Length of "pci-_xx_xx_x\0" */
@@ -213,10 +278,8 @@ int loader_get_user_preferred_fd(int default_fd, int 
*different_device)
prime = loader_get_dri_config_device_id();
  #endif
  
-   if (prime == NULL) {

-  *different_device = 0;
-  return default_fd;
-   }
+   if (prime == NULL || *prime == '\0')
+  return drm_detect_prime_fd(default_fd, different_device);
  
 default_tag = drm_get_id_path_tag_for_fd(default_fd);

 if (default_tag == NULL)



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC] loader: Automatic PRIME detection

2016-12-23 Thread Thierry Reding
From: Thierry Reding 

If a device doesn't support rendering and support for PRIME isn't
enabled via the DRI_PRIME environment variable or dri.conf, attempt to
find a render node which can be used to offload rendering.

Signed-off-by: Thierry Reding 
---
Along with platform and host1x bus support in the loader, this is the
final piece of the puzzle to automatically allow split scanout/render
devices to work with Wayland compositors and the X.Org server.

Note that this requires that the Wayland compositor and X.Org server
are accelerated with a DRI driver to make sure that the default file
descriptor is properly set up.

 src/loader/loader.c | 71 ++---
 1 file changed, 67 insertions(+), 4 deletions(-)

diff --git a/src/loader/loader.c b/src/loader/loader.c
index 505c33133be6..6384432970f2 100644
--- a/src/loader/loader.c
+++ b/src/loader/loader.c
@@ -108,6 +108,71 @@ static char *loader_get_dri_config_device_id(void)
 }
 #endif
 
+/*
+ * For all devices that do not support rendering, try to find a different
+ * device that will.
+ *
+ * Note that the absence of a render node doesn't technically imply that
+ * the device can't render, but in practice this should work out fine.
+ */
+static int drm_detect_prime_fd(int default_fd, int *different_device)
+{
+   int err, fd = -ENODEV;
+   drmDevicePtr device;
+
+   err = drmGetDevice(default_fd, );
+   if (err < 0)
+  goto err;
+
+   if ((device->available_nodes & (1 << DRM_NODE_RENDER)) == 0) {
+  unsigned int num_devices, i;
+  drmDevicePtr *devices;
+
+  err = drmGetDevices(NULL, 0);
+  if (err < 0)
+ goto err;
+
+  num_devices = err;
+
+  devices = calloc(num_devices, sizeof(drmDevicePtr));
+  if (!devices)
+ goto err;
+
+  err = drmGetDevices(devices, num_devices);
+  if (err < 0) {
+ free(devices);
+ goto err;
+  }
+
+  num_devices = err;
+
+  for (i = 0; i < num_devices; i++) {
+ if (devices[i]->available_nodes & (1 << DRM_NODE_RENDER)) {
+fd = loader_open_device(devices[i]->nodes[DRM_NODE_RENDER]);
+if (fd < 0) {
+   fd = -errno;
+   continue;
+}
+
+close(default_fd);
+break;
+ }
+  }
+
+  drmFreeDevices(devices, num_devices);
+  free(devices);
+   }
+
+err:
+   if (fd < 0) {
+  *different_device = 0;
+  return default_fd;
+   }
+
+   *different_device = 1;
+   return fd;
+}
+
 static char *drm_construct_id_path_tag(drmDevicePtr device)
 {
 /* Length of "pci-_xx_xx_x\0" */
@@ -213,10 +278,8 @@ int loader_get_user_preferred_fd(int default_fd, int 
*different_device)
   prime = loader_get_dri_config_device_id();
 #endif
 
-   if (prime == NULL) {
-  *different_device = 0;
-  return default_fd;
-   }
+   if (prime == NULL || *prime == '\0')
+  return drm_detect_prime_fd(default_fd, different_device);
 
default_tag = drm_get_id_path_tag_for_fd(default_fd);
if (default_tag == NULL)
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev