summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMario Kleiner <[email protected]>2018-06-13 06:04:15 +0200
committerAdam Jackson <[email protected]>2019-01-29 20:03:20 +0000
commit820dfcea431e4f96f25e6b340edd9cd1e449158b (patch)
tree1964b1200cc3fb9b8e99305011187d175ae250ca
parenta34b0d68bbf8571e4d858cf4e1176766a50364de (diff)
egl/wayland-drm: Only announce formats via wl_drm which the driver supports.
Check if a pixel format is supported by the Wayland servers gpu driver before exposing it to the client via wl_drm, so we avoid reporting formats to the client which the server gpu can't handle. Restrict this reporting to the new color depth 30 formats for now, as the ARGB/XRGB8888 and RGB565 formats are probably supported by every gpu under the sun. Atm. this is mostly useful to allow proper PRIME renderoffload for depth 30 formats on the typical Intel iGPU + NVidia dGPU "NVidia Optimus" laptop combo. Tested on Intel, AMD, NVidia with single-gpu setup and on a Intel + NVidia Optimus setup. Signed-off-by: Mario Kleiner <[email protected]> Reviewed-by: Adam Jackson <[email protected]> Reviewed-by: Daniel Stone <[email protected]>
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c3
-rw-r--r--src/egl/drivers/dri2/egl_dri2.h2
-rw-r--r--src/egl/drivers/dri2/platform_wayland.c18
-rw-r--r--src/egl/wayland/wayland-drm/wayland-drm.c31
-rw-r--r--src/egl/wayland/wayland-drm/wayland-drm.h2
5 files changed, 51 insertions, 5 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 892e32dd4e3..c98b9a5d18a 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -2797,7 +2797,8 @@ dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp,
const struct wayland_drm_callbacks wl_drm_callbacks = {
.authenticate = (int(*)(void *, uint32_t)) dri2_dpy->vtbl->authenticate,
.reference_buffer = dri2_wl_reference_buffer,
- .release_buffer = dri2_wl_release_buffer
+ .release_buffer = dri2_wl_release_buffer,
+ .is_format_supported = dri2_wl_is_format_supported
};
int flags = 0;
uint64_t cap;
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 726ba16ae61..a9ddadf11b1 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -458,6 +458,8 @@ EGLBoolean
dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp);
void
dri2_teardown_wayland(struct dri2_egl_display *dri2_dpy);
+bool
+dri2_wl_is_format_supported(void* user_data, uint32_t format);
#else
static inline EGLBoolean
dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 872e265f509..c3ca1b6f7bc 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -174,6 +174,24 @@ dri2_wl_visual_idx_from_shm_format(uint32_t shm_format)
return -1;
}
+bool
+dri2_wl_is_format_supported(void* user_data, uint32_t format)
+{
+ _EGLDisplay *disp = (_EGLDisplay *) user_data;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ int j = dri2_wl_visual_idx_from_fourcc(format);
+
+ if (j == -1)
+ return false;
+
+ for (int i = 0; dri2_dpy->driver_configs[i]; i++)
+ if (j == dri2_wl_visual_idx_from_config(dri2_dpy,
+ dri2_dpy->driver_configs[i]))
+ return true;
+
+ return false;
+}
+
static int
roundtrip(struct dri2_egl_display *dri2_dpy)
{
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.c b/src/egl/wayland/wayland-drm/wayland-drm.c
index 3c6696dbffb..51cdd2cb845 100644
--- a/src/egl/wayland/wayland-drm/wayland-drm.c
+++ b/src/egl/wayland/wayland-drm/wayland-drm.c
@@ -111,6 +111,8 @@ drm_create_buffer(struct wl_client *client, struct wl_resource *resource,
uint32_t stride, uint32_t format)
{
switch (format) {
+ case WL_DRM_FORMAT_ABGR2101010:
+ case WL_DRM_FORMAT_XBGR2101010:
case WL_DRM_FORMAT_ARGB2101010:
case WL_DRM_FORMAT_XRGB2101010:
case WL_DRM_FORMAT_ARGB8888:
@@ -210,10 +212,31 @@ bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id)
wl_resource_set_implementation(resource, &drm_interface, data, NULL);
wl_resource_post_event(resource, WL_DRM_DEVICE, drm->device_name);
- wl_resource_post_event(resource, WL_DRM_FORMAT,
- WL_DRM_FORMAT_ARGB2101010);
- wl_resource_post_event(resource, WL_DRM_FORMAT,
- WL_DRM_FORMAT_XRGB2101010);
+
+ if (drm->callbacks.is_format_supported(drm->user_data,
+ WL_DRM_FORMAT_ARGB2101010)) {
+ wl_resource_post_event(resource, WL_DRM_FORMAT,
+ WL_DRM_FORMAT_ARGB2101010);
+ }
+
+ if (drm->callbacks.is_format_supported(drm->user_data,
+ WL_DRM_FORMAT_XRGB2101010)) {
+ wl_resource_post_event(resource, WL_DRM_FORMAT,
+ WL_DRM_FORMAT_XRGB2101010);
+ }
+
+ if (drm->callbacks.is_format_supported(drm->user_data,
+ WL_DRM_FORMAT_ABGR2101010)) {
+ wl_resource_post_event(resource, WL_DRM_FORMAT,
+ WL_DRM_FORMAT_ABGR2101010);
+ }
+
+ if (drm->callbacks.is_format_supported(drm->user_data,
+ WL_DRM_FORMAT_XBGR2101010)) {
+ wl_resource_post_event(resource, WL_DRM_FORMAT,
+ WL_DRM_FORMAT_XBGR2101010);
+ }
+
wl_resource_post_event(resource, WL_DRM_FORMAT,
WL_DRM_FORMAT_ARGB8888);
wl_resource_post_event(resource, WL_DRM_FORMAT,
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.h b/src/egl/wayland/wayland-drm/wayland-drm.h
index 36e5bf042a7..8b7fd3b0b64 100644
--- a/src/egl/wayland/wayland-drm/wayland-drm.h
+++ b/src/egl/wayland/wayland-drm/wayland-drm.h
@@ -14,6 +14,8 @@ struct wayland_drm_callbacks {
struct wl_drm_buffer *buffer);
void (*release_buffer)(void *user_data, struct wl_drm_buffer *buffer);
+
+ bool (*is_format_supported)(void *user_data, uint32_t format);
};