Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
- index 1bce314..7e9b683 100644
- --- a/src/egl/drivers/dri2/egl_dri2.c
- +++ b/src/egl/drivers/dri2/egl_dri2.c
- @@ -1573,7 +1573,7 @@ dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp,
- (int(*)(void *, uint32_t)) dri2_dpy->authenticate;
- ret = drmGetCap(dri2_dpy->fd, DRM_CAP_PRIME, &cap);
- - if (ret == 0 && cap == (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT) &&
- + if (ret == 0 && (cap & DRM_PRIME_CAP_IMPORT) &&
- dri2_dpy->image->base.version >= 7 &&
- dri2_dpy->image->createImageFromFds != NULL)
- flags |= WAYLAND_DRM_PRIME;
- diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
- index 6dfdf94..aff39b2 100644
- --- a/src/egl/drivers/dri2/egl_dri2.h
- +++ b/src/egl/drivers/dri2/egl_dri2.h
- @@ -133,6 +133,8 @@ struct dri2_egl_display
- int authenticated;
- int formats;
- uint32_t capabilities;
- + int use_prime;
- + int wanted_id;
- #endif
- int (*authenticate) (_EGLDisplay *disp, uint32_t id);
- diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
- index 1d417bb..b285ea9 100644
- --- a/src/egl/drivers/dri2/platform_wayland.c
- +++ b/src/egl/drivers/dri2/platform_wayland.c
- @@ -461,9 +461,14 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf)
- if (dri2_surf->current->wl_buffer != NULL)
- return;
- - if (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) {
- + if (dri2_dpy->use_prime) {
- + __DRIimage* image = dri2_surf->current->dri_image;
- + uint32_t handle;
- + int res;
- dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
- - __DRI_IMAGE_ATTRIB_FD, &fd);
- + __DRI_IMAGE_ATTRIB_HANDLE,&handle);
- + res=drmPrimeHandleToFD(dri2_dpy->fd,handle,DRM_CLOEXEC,&fd);
- + _eglLog(_EGL_WARNING,"res %i:fd: %i, handle: %i",res,fd,handle);
- dri2_surf->current->wl_buffer =
- wl_drm_create_prime_buffer(dri2_dpy->wl_drm,
- @@ -632,16 +637,19 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
- return EGL_TRUE;
- }
- +
- +
- static void
- drm_handle_device(void *data, struct wl_drm *drm, const char *device)
- {
- struct dri2_egl_display *dri2_dpy = data;
- drm_magic_t magic;
- -
- + if(dri2_dpy->wanted_id != 0)
- + return;
- dri2_dpy->device_name = strdup(device);
- if (!dri2_dpy->device_name)
- return;
- -
- + _eglLog(_EGL_WARNING, "using main card: %s", device);
- #ifdef O_CLOEXEC
- dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
- if (dri2_dpy->fd == -1 && errno == EINVAL)
- @@ -691,13 +699,49 @@ drm_handle_authenticated(void *data, struct wl_drm *drm)
- struct dri2_egl_display *dri2_dpy = data;
- dri2_dpy->authenticated = 1;
- + if (dri2_dpy->wanted_id != 0)
- + dri2_dpy->use_prime = 1;
- + else
- + dri2_dpy->use_prime = 0;
- +}
- +
- +static void
- +drm_handle_prime_device(void *data, struct wl_drm *drm, const char *device, uint32_t id)
- +{
- + struct dri2_egl_display *dri2_dpy = data;
- + drm_magic_t magic;
- + if(dri2_dpy->wanted_id != id)
- + return;
- + dri2_dpy->device_name = strdup(device);
- + if (!dri2_dpy->device_name)
- + return;
- + _eglLog(_EGL_WARNING, "using card: %s", device);
- +#ifdef O_CLOEXEC
- + dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
- + if (dri2_dpy->fd == -1 && errno == EINVAL)
- +#endif
- + {
- + dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
- + if (dri2_dpy->fd != -1)
- + fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) |
- + FD_CLOEXEC);
- + }
- + if (dri2_dpy->fd == -1) {
- + _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
- + dri2_dpy->device_name, strerror(errno));
- + return;
- + }
- +
- + drmGetMagic(dri2_dpy->fd, &magic);
- + wl_drm_authenticate(dri2_dpy->wl_drm, magic);
- }
- static const struct wl_drm_listener drm_listener = {
- drm_handle_device,
- drm_handle_format,
- drm_handle_authenticated,
- - drm_handle_capabilities
- + drm_handle_capabilities,
- + drm_handle_prime_device
- };
- static void
- @@ -706,8 +750,8 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
- {
- struct dri2_egl_display *dri2_dpy = data;
- - if (version > 1)
- - version = 2;
- + if (version > 2)
- + version = 3;
- if (strcmp(interface, "wl_drm") == 0) {
- dri2_dpy->wl_drm =
- wl_registry_bind(registry, name, &wl_drm_interface, version);
- @@ -757,7 +801,16 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
- } else {
- dri2_dpy->wl_dpy = disp->PlatformDisplay;
- }
- -
- +
- + dri2_dpy->wanted_id=0;
- + {
- + char *prime = getenv("DRI_PRIME");
- + if (prime)
- + {
- + dri2_dpy->wanted_id=1; //TODO: if fails, do a second loop with id = 0. (no corresponding id)
- + }
- + }
- +
- dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
- if (dri2_dpy->own_device)
- diff --git a/src/egl/wayland/wayland-drm/Makefile.am b/src/egl/wayland/wayland-drm/Makefile.am
- index 4b2aeb3..66f7a08 100644
- --- a/src/egl/wayland/wayland-drm/Makefile.am
- +++ b/src/egl/wayland/wayland-drm/Makefile.am
- @@ -1,6 +1,8 @@
- AM_CFLAGS = -I$(top_srcdir)/src/egl/main \
- -I$(top_srcdir)/include \
- $(DEFINES) \
- + $(LIBDRM_CFLAGS) \
- + $(LIBUDEV_CFLAGS) \
- $(WAYLAND_CFLAGS)
- noinst_LTLIBRARIES = libwayland-drm.la
- diff --git a/src/egl/wayland/wayland-drm/wayland-drm.c b/src/egl/wayland/wayland-drm/wayland-drm.c
- index 7e2073a..d9a7b46 100644
- --- a/src/egl/wayland/wayland-drm/wayland-drm.c
- +++ b/src/egl/wayland/wayland-drm/wayland-drm.c
- @@ -25,6 +25,7 @@
- * Authors:
- * Kristian Høgsberg <krh@bitplanet.net>
- * Benjamin Franzke <benjaminfranzke@googlemail.com>
- + * Axel Davy
- */
- #include <stdio.h>
- @@ -32,21 +33,133 @@
- #include <string.h>
- #include <stddef.h>
- #include <unistd.h>
- +#include <errno.h>
- +#include <c99/stdbool.h>
- +#include <xf86drm.h>
- +#include <fcntl.h>
- +#include <dlfcn.h>
- #include <wayland-server.h>
- #include "wayland-drm.h"
- #include "wayland-drm-server-protocol.h"
- +
- +struct prime_device{
- + char* device_name;
- + uint32_t id;
- + int fd;
- + bool opened;
- + bool is_master;
- + struct prime_device* next_prime_device;
- + struct prime_device* prec_prime_device; //doubly linked list
- +};
- +
- struct wl_drm {
- struct wl_display *display;
- void *user_data;
- - char *device_name;
- - uint32_t flags;
- + char *main_device_name;
- + uint32_t main_device_flags;
- +
- + struct prime_device *prime_devices;
- struct wayland_drm_callbacks *callbacks;
- };
- +static bool device_be_master(struct prime_device *prime_device) // assumes device is open
- +{
- + if(drmSetMaster(prime_device->fd)==0) // will work if we are already master
- + {
- + prime_device->is_master=true;
- + return true;
- + }
- + return false;
- +
- +}
- +
- +static int hashBusid(char* str)
- +{
- + return 1; //TODO
- +}
- +
- +
- +
- +static bool open_device(struct prime_device *prime_device)
- +{
- + uint64_t cap;
- + #ifdef O_CLOEXEC
- + prime_device->fd = open(prime_device->device_name, O_RDWR | O_CLOEXEC);
- + if (prime_device->fd == -1 && errno == EINVAL)
- + #endif
- + {
- + prime_device->fd = open(prime_device->device_name, O_RDWR);
- + if (prime_device->fd != -1)
- + fcntl(prime_device->fd, F_SETFD, fcntl(prime_device->fd, F_GETFD) |
- + FD_CLOEXEC);
- + }
- +
- + if (prime_device->fd == -1)
- + return false;
- +
- +
- + drmGetCap(prime_device->fd, DRM_CAP_PRIME, &cap); // maybe should test if it fails (old kernel)
- + if (!(cap & DRM_PRIME_CAP_EXPORT))
- + {
- + close(prime_device->fd);
- + return false;
- + }
- + prime_device->opened = true;
- + prime_device->id = hashBusid(drmGetBusid(prime_device->fd));
- + return true; // we don't become master of the device yet, we will do it only when required.
- +}
- +
- +
- +static void discover_prime_devices(struct wl_drm *drm)
- +{
- +//TODO
- + // ADD main_device. already master. already opened.
- + drm->prime_devices = (struct prime_device*) malloc(sizeof(struct prime_device));
- + drm->prime_devices->device_name = strdup(drm->main_device_name);
- + drm->prime_devices->id = 0; //TODO
- + drm->prime_devices->fd = -1;//drm->fd;
- + drm->prime_devices->opened = true;
- + drm->prime_devices->is_master = true;
- + drm->prime_devices->next_prime_device = NULL;
- + drm->prime_devices->prec_prime_device = NULL;
- +
- + //ADD other devices
- + struct prime_device* p = (struct prime_device*) malloc(sizeof(struct prime_device));
- + if (strcmp("/dev/dri/card0",drm->main_device_name) == 0)
- + p->device_name = strdup("/dev/dri/card1");
- + else
- + p->device_name = strdup("/dev/dri/card0");
- + p->opened = false;
- + p->is_master = false;
- + p->next_prime_device = NULL;
- + p->prec_prime_device = drm->prime_devices;
- + if (open_device(p))
- + drm->prime_devices->next_prime_device = p;
- + else
- + {
- + free(p->device_name);
- + free(p);
- + }
- + return;
- +
- +}
- +
- +static bool authenticate_prime_devices(struct prime_device *prime_devices, uint32_t id)
- +{
- + struct prime_device * p = prime_devices;
- + while (p!=NULL)
- + {
- + if ((p->id !=0) && (p->opened || open_device(p) ) && (p->is_master || device_be_master(p)) && (drmAuthMagic(p->fd,id)==0))
- + return true;
- + p = p->next_prime_device;
- + }
- +return false;
- +}
- +
- static void
- destroy_buffer(struct wl_resource *resource)
- {
- @@ -67,6 +180,7 @@ const static struct wl_buffer_interface drm_buffer_interface = {
- buffer_destroy
- };
- +
- static void
- create_buffer(struct wl_client *client, struct wl_resource *resource,
- uint32_t id, uint32_t name, int fd,
- @@ -180,13 +294,15 @@ drm_create_prime_buffer(struct wl_client *client,
- close(fd);
- }
- +
- +
- static void
- drm_authenticate(struct wl_client *client,
- struct wl_resource *resource, uint32_t id)
- {
- struct wl_drm *drm = resource->data;
- - if (drm->callbacks->authenticate(drm->user_data, id) < 0)
- + if (drm->callbacks->authenticate(drm->user_data, id) < 0 && !(authenticate_prime_devices(drm->prime_devices,id)))
- wl_resource_post_error(resource,
- WL_DRM_ERROR_AUTHENTICATE_FAIL,
- "authenicate failed");
- @@ -194,6 +310,8 @@ drm_authenticate(struct wl_client *client,
- wl_resource_post_event(resource, WL_DRM_AUTHENTICATED);
- }
- +
- +
- const static struct wl_drm_interface drm_interface = {
- drm_authenticate,
- drm_create_buffer,
- @@ -210,7 +328,7 @@ bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id)
- resource = wl_client_add_object(client, &wl_drm_interface,
- &drm_interface, id, data);
- - wl_resource_post_event(resource, WL_DRM_DEVICE, drm->device_name);
- + wl_resource_post_event(resource, WL_DRM_DEVICE, drm->main_device_name);
- wl_resource_post_event(resource, WL_DRM_FORMAT,
- WL_DRM_FORMAT_ARGB8888);
- wl_resource_post_event(resource, WL_DRM_FORMAT,
- @@ -225,8 +343,20 @@ bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id)
- wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUYV);
- capabilities = 0;
- - if (drm->flags & WAYLAND_DRM_PRIME)
- - capabilities |= WL_DRM_CAPABILITY_PRIME;
- + if (drm->main_device_flags & WAYLAND_DRM_PRIME)
- + {
- + capabilities |= WL_DRM_CAPABILITY_PRIME;
- + if (version >= 3)
- + {
- + struct prime_device* p = drm->prime_devices;
- + while (p!=NULL)
- + {
- + if(p->id!=0) // fix: already advertised main device
- + wl_resource_post_event(resource, WL_DRM_PRIME_DEVICE, p->device_name, p->id);
- + p = p->next_prime_device;
- + }
- + }
- + }
- if (version >= 2)
- wl_resource_post_event(resource, WL_DRM_CAPABILITIES, capabilities);
- @@ -242,10 +372,12 @@ wayland_drm_init(struct wl_display *display, char *device_name,
- drm = malloc(sizeof *drm);
- drm->display = display;
- - drm->device_name = strdup(device_name);
- + drm->main_device_name = strdup(device_name);
- drm->callbacks = callbacks;
- drm->user_data = user_data;
- - drm->flags = flags;
- + drm->main_device_flags = flags; //drmGetCap(fd,DRM_CAP_PRIME,&p) DRM_PRIME_CAP_IMPORT
- + if (flags & WAYLAND_DRM_PRIME)
- + discover_prime_devices(drm);
- wl_display_add_global(display, &wl_drm_interface, drm, bind_drm);
- @@ -255,8 +387,28 @@ wayland_drm_init(struct wl_display *display, char *device_name,
- void
- wayland_drm_uninit(struct wl_drm *drm)
- {
- - free(drm->device_name);
- -
- + free(drm->main_device_name);
- + struct prime_device * p = drm->prime_devices;
- + struct prime_device * p_last = drm->prime_devices;
- + while (p!=NULL)
- + {
- + if (p->opened && p->id !=0) // do not close main_device todo
- + {
- + if (p->is_master)
- + drmDropMaster(p->fd);
- + close(p->fd);
- + }
- + free(p->device_name);
- + p_last = p;
- + p = p->next_prime_device;
- + }
- + while (p_last!=NULL)
- + {
- + struct prime_device * p_temp = p->prec_prime_device;
- + free(p_last);
- + p_last = p_temp;
- + }
- +
- /* FIXME: need wl_display_del_{object,global} */
- free(drm);
- diff --git a/src/egl/wayland/wayland-drm/wayland-drm.h b/src/egl/wayland/wayland-drm/wayland-drm.h
- index 335073a..1450ea4 100644
- --- a/src/egl/wayland/wayland-drm/wayland-drm.h
- +++ b/src/egl/wayland/wayland-drm/wayland-drm.h
- @@ -2,6 +2,8 @@
- #define WAYLAND_DRM_H
- #include <wayland-server.h>
- +#include <c99/stdbool.h>
- +
- #ifndef WL_DRM_FORMAT_ENUM
- #define WL_DRM_FORMAT_ENUM
- @@ -68,6 +70,7 @@ enum wl_drm_format {
- #endif /* WL_DRM_FORMAT_ENUM */
- struct wl_drm;
- +struct prime_device;
- struct wl_drm_buffer {
- struct wl_buffer buffer;
- @@ -79,6 +82,7 @@ struct wl_drm_buffer {
- void *driver_buffer;
- };
- +
- struct wayland_drm_callbacks {
- int (*authenticate)(void *user_data, uint32_t id);
- @@ -88,7 +92,8 @@ struct wayland_drm_callbacks {
- void (*release_buffer)(void *user_data, struct wl_drm_buffer *buffer);
- };
- -enum { WAYLAND_DRM_PRIME = 0x01 };
- +enum { WAYLAND_DRM_PRIME = 0x01};
- +
- struct wl_drm *
- wayland_drm_init(struct wl_display *display, char *device_name,
- @@ -107,4 +112,9 @@ wayland_drm_buffer_get_format(struct wl_buffer *buffer_base);
- void *
- wayland_drm_buffer_get_buffer(struct wl_buffer *buffer);
- +static bool open_device(struct prime_device *prime_device);
- +static void discover_prime_devices(struct wl_drm *drm);
- +static int hashBusid(char* str);
- +static bool authenticate_prime_devices(struct prime_device *prime_devices, uint32_t id);
- +
- #endif
- diff --git a/src/egl/wayland/wayland-drm/wayland-drm.xml b/src/egl/wayland/wayland-drm/wayland-drm.xml
- index 8a3ad69..64987a6 100644
- --- a/src/egl/wayland/wayland-drm/wayland-drm.xml
- +++ b/src/egl/wayland/wayland-drm/wayland-drm.xml
- @@ -29,7 +29,7 @@
- <!-- drm support. This object is created by the server and published
- using the display's global event. -->
- - <interface name="wl_drm" version="2">
- + <interface name="wl_drm" version="3">
- <enum name="error">
- <entry name="authenticate_fail" value="0"/>
- <entry name="invalid_format" value="1"/>
- @@ -150,16 +150,17 @@
- <arg name="offset2" type="int"/>
- <arg name="stride2" type="int"/>
- </request>
- -
- +
- <!-- Notification of the path of the drm device which is used by
- the server. The client should use this device for creating
- local buffers. Only buffers created from this device should
- be be passed to the server using this drm object's
- create_buffer request. -->
- +
- <event name="device">
- <arg name="name" type="string"/>
- </event>
- -
- +
- <event name="format">
- <arg name="format" type="uint"/>
- </event>
- @@ -177,6 +178,11 @@
- <event name="capabilities">
- <arg name="value" type="uint"/>
- </event>
- +
- + <event name="prime_device">
- + <arg name="name" type="string"/>
- + <arg name="id" type="uint"/>
- + </event>
- </interface>
- </protocol>
- diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
- index 36cca17..c5eb95c 100644
- --- a/src/gallium/drivers/r600/r600_texture.c
- +++ b/src/gallium/drivers/r600/r600_texture.c
- @@ -609,6 +609,7 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
- * because 422 formats are used for videos, which prefer linear buffers
- * for fast uploads anyway. */
- if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
- + !(templ->bind & PIPE_BIND_SHARED) &&
- desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
- if (templ->flags & R600_RESOURCE_FLAG_FORCE_TILING) {
- array_mode = V_038000_ARRAY_2D_TILED_THIN1;
- diff --git a/src/gallium/drivers/radeonsi/r600_texture.c b/src/gallium/drivers/radeonsi/r600_texture.c
- index 282d4f2..3cbe34b 100644
- --- a/src/gallium/drivers/radeonsi/r600_texture.c
- +++ b/src/gallium/drivers/radeonsi/r600_texture.c
- @@ -528,7 +528,7 @@ struct pipe_resource *si_texture_create(struct pipe_screen *screen,
- int r;
- if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
- - !(templ->bind & PIPE_BIND_SCANOUT)) {
- + !(templ->bind & (PIPE_BIND_SCANOUT| PIPE_BIND_SHARED))) {
- if (util_format_is_compressed(templ->format)) {
- array_mode = V_009910_ARRAY_1D_TILED_THIN1;
- } else {
- diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
- index 1dcc1f7..7ef8d15 100644
- --- a/src/gallium/state_trackers/dri/drm/dri2.c
- +++ b/src/gallium/state_trackers/dri/drm/dri2.c
- @@ -627,7 +627,7 @@ dri2_create_image(__DRIscreen *_screen,
- if (use & __DRI_IMAGE_USE_SCANOUT)
- tex_usage |= PIPE_BIND_SCANOUT;
- if (use & __DRI_IMAGE_USE_SHARE)
- - tex_usage |= PIPE_BIND_SHARED;
- + tex_usage |= PIPE_BIND_SHARED ;
- if (use & __DRI_IMAGE_USE_CURSOR) {
- if (width != 64 || height != 64)
- return NULL;
- @@ -721,6 +721,13 @@ dri2_query_image(__DRIimage *image, int attrib, int *value)
- return GL_FALSE;
- *value = image->dri_components;
- return GL_TRUE;
- + /* case __DRI_IMAGE_ATTRIB_FD:
- + whandle.type = DRM_API_HANDLE_TYPE_KMS;
- + image->texture->screen->resource_get_handle(image->texture->screen,
- + image->texture, &whandle);
- + if(drmPrimeHandleToFD(dri2_dpy->fd,whandle.handle,DRM_CLOEXEC,value)==0)
- + return GL_TRUE;
- + return GL_FALSE;*/
- default:
- return GL_FALSE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement