Commit 6b85aa68 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm: Enable PRIME import/export for all drivers



Call drm_gem_prime_handle_to_fd() and drm_gem_prime_fd_to_handle() by
default if no PRIME import/export helpers have been set. Both functions
are the default for almost all drivers.

DRM drivers implement struct drm_driver.gem_prime_import_sg_table
to import dma-buf objects from other drivers. Having the function
drm_gem_prime_fd_to_handle() functions set by default allows each
driver to import dma-buf objects to itself, even without support for
other drivers.

For drm_gem_prime_handle_to_fd() it is similar: using it by default
allows each driver to export to itself, even without support for other
drivers.

This functionality enables userspace to share per-driver buffers
across process boundaries via PRIME (e.g., wlroots requires this
functionality). The patch generalizes a pattern that has previously
been implemented by GEM VRAM helpers [1] to work with any driver.
For example, gma500 can now run the wlroots-based sway compositor.

v2:
	* clean up docs and TODO comments (Simon, Zack)
	* clean up style in drm_getcap()

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/dri-devel/20230302143502.500661-1-contact@emersion.fr/

 # 1
Reviewed-by: default avatarSimon Ser <contact@emersion.fr>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarJeffrey Hugo <quic_jhugo@quicinc.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230620080252.16368-2-tzimmermann@suse.de
parent aa656d48
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -245,8 +245,7 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
		req->value = 1;
		return 0;
	case DRM_CAP_PRIME:
		req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
		req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0;
		req->value = DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT;
		return 0;
	case DRM_CAP_SYNCOBJ:
		req->value = drm_core_check_feature(dev, DRIVER_SYNCOBJ);
+12 −9
Original line number Diff line number Diff line
@@ -372,11 +372,12 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
{
	struct drm_prime_handle *args = data;

	if (!dev->driver->prime_fd_to_handle)
		return -ENOSYS;
	if (dev->driver->prime_fd_to_handle) {
		return dev->driver->prime_fd_to_handle(dev, file_priv, args->fd,
						       &args->handle);
	}

	return dev->driver->prime_fd_to_handle(dev, file_priv,
			args->fd, &args->handle);
	return drm_gem_prime_fd_to_handle(dev, file_priv, args->fd, &args->handle);
}

static struct dma_buf *export_and_register_object(struct drm_device *dev,
@@ -518,15 +519,17 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
{
	struct drm_prime_handle *args = data;

	if (!dev->driver->prime_handle_to_fd)
		return -ENOSYS;

	/* check flags are valid */
	if (args->flags & ~(DRM_CLOEXEC | DRM_RDWR))
		return -EINVAL;

	if (dev->driver->prime_handle_to_fd) {
		return dev->driver->prime_handle_to_fd(dev, file_priv,
			args->handle, args->flags, &args->fd);
						       args->handle, args->flags,
						       &args->fd);
	}
	return drm_gem_prime_handle_to_fd(dev, file_priv, args->handle,
					  args->flags, &args->fd);
}

/**
+2 −10
Original line number Diff line number Diff line
@@ -304,22 +304,14 @@ struct drm_driver {
	/**
	 * @prime_handle_to_fd:
	 *
	 * Main PRIME export function. Should be implemented with
	 * drm_gem_prime_handle_to_fd() for GEM based drivers.
	 *
	 * For an in-depth discussion see :ref:`PRIME buffer sharing
	 * documentation <prime_buffer_sharing>`.
	 * PRIME export function. Only used by vmwgfx.
	 */
	int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv,
				uint32_t handle, uint32_t flags, int *prime_fd);
	/**
	 * @prime_fd_to_handle:
	 *
	 * Main PRIME import function. Should be implemented with
	 * drm_gem_prime_fd_to_handle() for GEM based drivers.
	 *
	 * For an in-depth discussion see :ref:`PRIME buffer sharing
	 * documentation <prime_buffer_sharing>`.
	 * PRIME import function. Only used by vmwgfx.
	 */
	int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv,
				int prime_fd, uint32_t *handle);