[PATCH xf86-video-amdgpu 13/13] Add DRI3 support

Reverend Homer mk.43.ecko at gmail.com
Wed Jun 3 11:35:29 PDT 2015



On 02.06.2015 12:21, Michel Dänzer wrote:
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> Must be enabled with
>
> 	Option	"DRI3"
>
> in xorg.conf.
>
> (Cherry picked from radeon commits 64e1e4dbdd3caee6f5d8f6b6c094b4533fa94953,
> 694e04720b886060fe3eefdce59741f218c8269f,
> f940fd741b15f03393037c5bb904cd74f012de9d,
> fcd37f65f485291084c174666bd605e215bf1398,
> 4b0997e56dec0053cb2cb793e0f4ae35055ff7e6,
> f68d9b5ba0c91a725b5eec9386c61bea8824c299 and
> 98fb4199e63fedd4607cddee64bf602d6398df81)
>
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
> ---
>   configure.ac      |   4 ++
>   man/amdgpu.man    |   4 ++
>   src/Makefile.am   |   4 +-
>   src/amdgpu_dri3.c | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   src/amdgpu_drv.h  |   6 +-
>   src/amdgpu_kms.c  |  20 +++++-
>   6 files changed, 229 insertions(+), 5 deletions(-)
>   create mode 100644 src/amdgpu_dri3.c
>
> diff --git a/configure.ac b/configure.ac
> index b91ce17..d9d97ef 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -168,6 +168,10 @@ AC_CHECK_HEADERS([present.h], [], [],
>   		 #include <X11/X.h>
>   		 #include "xorg-server.h"])
>   
> +AC_CHECK_HEADERS([dri3.h], [], [],
> +		 [#include <X11/Xmd.h>
> +		 #include <xorg-server.h>])
> +
>   CPPFLAGS="$SAVE_CPPFLAGS"
>   
>   PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0])
> diff --git a/man/amdgpu.man b/man/amdgpu.man
> index 64633b3..bc7bf30 100644
> --- a/man/amdgpu.man
> +++ b/man/amdgpu.man
> @@ -70,6 +70,10 @@ For example:
>   Option \*qZaphodHeads\*q \*qLVDS,VGA-0\*q
>   will assign xrandr outputs LVDS and VGA-0 to this instance of the driver.
>   .TP
> +.BI "Option \*qDRI3\*q \*q" boolean \*q
> +Enable the DRI3 extension. The default is
> +.B off.
> +.TP
>   .BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
>   Enable DRI2 page flipping.  The default is
>   .B on.
> diff --git a/src/Makefile.am b/src/Makefile.am
> index fc8b77a..b953d4c 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -28,8 +28,8 @@
>   
>   amdgpu_drv_la_LIBADD = $(PCIACCESS_LIBS) $(LIBDRM_AMDGPU_LIBS) $(GBM_LIBS)
>   
> -AMDGPU_KMS_SRCS=amdgpu_bo_helper.c amdgpu_dri2.c amdgpu_drm_queue.c amdgpu_kms.c \
> -	amdgpu_present.c amdgpu_sync.c drmmode_display.c
> +AMDGPU_KMS_SRCS=amdgpu_bo_helper.c amdgpu_dri2.c amdgpu_dri3.c amdgpu_drm_queue.c \
> +	amdgpu_kms.c amdgpu_present.c amdgpu_sync.c drmmode_display.c
>   
>   AM_CFLAGS = \
>               @GBM_CFLAGS@ \
> diff --git a/src/amdgpu_dri3.c b/src/amdgpu_dri3.c
> new file mode 100644
> index 0000000..ce0f8e7
> --- /dev/null
> +++ b/src/amdgpu_dri3.c
> @@ -0,0 +1,196 @@
> +/*
> + * Copyright © 2013-2014 Intel Corporation
> + * Copyright © 2015 Advanced Micro Devices, Inc.
> + *
> + * Permission to use, copy, modify, distribute, and sell this software and its
> + * documentation for any purpose is hereby granted without fee, provided that
> + * the above copyright notice appear in all copies and that both that copyright
> + * notice and this permission notice appear in supporting documentation, and
> + * that the name of the copyright holders not be used in advertising or
> + * publicity pertaining to distribution of the software without specific,
> + * written prior permission.  The copyright holders make no representations
> + * about the suitability of this software for any purpose.  It is provided "as
> + * is" without express or implied warranty.
> + *
> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
> + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
> + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
> + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
> + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
> + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
> + * OF THIS SOFTWARE.
> + */
> +
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include "amdgpu_drv.h"
> +
> +#ifdef HAVE_DRI3_H
> +
> +#include "amdgpu_glamor.h"
> +#include "amdgpu_pixmap.h"
> +#include "dri3.h"
> +
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +
> +
> +static int
> +amdgpu_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out)
> +{
> +	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> +	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
> +	drm_magic_t magic;
> +	int fd;
> +
> +	fd = open(info->dri2.device_name, O_RDWR | O_CLOEXEC);
> +	if (fd < 0)
> +		return BadAlloc;
> +
> +	/* Before FD passing in the X protocol with DRI3 (and increased
> +	 * security of rendering with per-process address spaces on the
> +	 * GPU), the kernel had to come up with a way to have the server
> +	 * decide which clients got to access the GPU, which was done by
> +	 * each client getting a unique (magic) number from the kernel,
> +	 * passing it to the server, and the server then telling the
> +	 * kernel which clients were authenticated for using the device.
> +	 *
> +	 * Now that we have FD passing, the server can just set up the
> +	 * authentication on its own and hand the prepared FD off to the
> +	 * client.
> +	 */
> +	if (drmGetMagic(fd, &magic) < 0) {
> +		if (errno == EACCES) {
> +			/* Assume that we're on a render node, and the fd is
> +			 * already as authenticated as it should be.
> +			 */
> +			*out = fd;
> +			return Success;
> +		} else {
> +			close(fd);
> +			return BadMatch;
> +		}
> +	}
> +
> +	if (drmAuthMagic(info->dri2.drm_fd, magic) < 0) {
> +		close(fd);
> +		return BadMatch;
> +	}
> +
> +	*out = fd;
> +	return Success;
> +}
> +
> +static PixmapPtr amdgpu_dri3_pixmap_from_fd(ScreenPtr screen,
> +					    int fd,
> +					    CARD16 width,
> +					    CARD16 height,
> +					    CARD16 stride,
> +					    CARD8 depth,
> +					    CARD8 bpp)
> +{
> +	PixmapPtr pixmap;
> +
> +	if (depth < 8)
> +		return NULL;
> +
> +	switch (bpp) {
> +	case 8:
> +	case 16:
> +	case 32:
> +		break;
> +	default:
> +		return NULL;
> +	}
> +
> +	pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
> +	if (!pixmap)
> +		return NULL;
> +
> +	if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, bpp, stride,
> +					NULL))
> +		goto free_pixmap;
> +
> +	if (screen->SetSharedPixmapBacking(pixmap, (void*)(intptr_t)fd))
> +		return pixmap;
> +
> +free_pixmap:
> +	fbDestroyPixmap(pixmap);
> +	return NULL;
> +}
> +
> +static int amdgpu_dri3_fd_from_pixmap(ScreenPtr screen,
> +				      PixmapPtr pixmap,
> +				      CARD16 *stride,
> +				      CARD32 *size)
> +{
> +	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> +	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
> +	struct amdgpu_buffer *bo;
> +	struct amdgpu_bo_info bo_info;
> +	uint32_t fd;
> +
> +#ifdef USE_GLAMOR
> +	if (info->use_glamor)
> +		return glamor_fd_from_pixmap(screen, pixmap, stride, size);
> +#endif
> +
> +	bo = amdgpu_get_pixmap_bo(pixmap);
> +	if (!bo)
> +		return -1;
> +
> +	if (pixmap->devKind > UINT16_MAX)
> +		return -1;
> +
> +	if (amdgpu_bo_query_info(bo->bo.amdgpu, &bo_info) != 0)
> +		return -1;
> +
> +	if (amdgpu_bo_export(bo->bo.amdgpu, amdgpu_bo_handle_type_dma_buf_fd,
> +			     &fd) != 0)
> +		return -1;
> +
> +	*stride = pixmap->devKind;
> +	*size = bo_info.alloc_size;
> +	return fd;
> +}
> +
> +static dri3_screen_info_rec amdgpu_dri3_screen_info = {
> +	.version = 0,
> +
> +	.open = amdgpu_dri3_open,
> +	.pixmap_from_fd = amdgpu_dri3_pixmap_from_fd,
> +	.fd_from_pixmap = amdgpu_dri3_fd_from_pixmap
> +};
> +
> +Bool
> +amdgpu_dri3_screen_init(ScreenPtr screen)
> +{
> +	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> +
> +	if (!dri3_screen_init(screen, &amdgpu_dri3_screen_info)) {
> +		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
> +			   "dri3_screen_init failed\n");
> +		return FALSE;
> +	}
> +
> +	return TRUE;
> +}
> +
> +#else /* !HAVE_DRI3_H */
> +
> +Bool
> +amdgpu_dri3_screen_init(ScreenPtr screen)
> +{
> +	xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
> +		   "Can't initialize DRI3 because dri3.h not available at "
> +		   "build time\n");
> +
> +	return FALSE;
> +}
> +
> +#endif
> diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
> index c6c968f..5ffbc6a 100644
> --- a/src/amdgpu_drv.h
> +++ b/src/amdgpu_drv.h
> @@ -140,7 +140,8 @@ typedef enum {
>   	OPTION_SUBPIXEL_ORDER,
>   #endif
>   	OPTION_ZAPHOD_HEADS,
> -	OPTION_ACCEL_METHOD
> +	OPTION_ACCEL_METHOD,
> +	OPTION_DRI3,
>   } AMDGPUOpts;
>   
>   #define AMDGPU_VSYNC_TIMEOUT	20000	/* Maximum wait for VSYNC (in usecs) */
> @@ -233,6 +234,9 @@ typedef struct {
>   } AMDGPUInfoRec, *AMDGPUInfoPtr;
>   
>   
> +/* amdgpu_dri3.c */
> +Bool amdgpu_dri3_screen_init(ScreenPtr screen);
> +
>   /* amdgpu_present.c */
>   Bool amdgpu_present_screen_init(ScreenPtr screen);
>   
> diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
> index 05e9adf..1e256af 100644
> --- a/src/amdgpu_kms.c
> +++ b/src/amdgpu_kms.c
> @@ -66,6 +66,7 @@ const OptionInfoRec AMDGPUOptions_KMS[] = {
>   	{OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE},
>   	{OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE},
>   	{OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE},
> +	{ OPTION_DRI3, "DRI3", OPTV_BOOLEAN, {0}, FALSE },
>   	{-1, NULL, OPTV_NONE, {0}, FALSE}
>   };
>   
> @@ -738,6 +739,8 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
>   	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
>   	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
>   	int subPixelOrder = SubPixelUnknown;
> +	MessageType from;
> +	Bool value;
>   	char *s;
>   	void *front_ptr;
>   	int ret;
> @@ -827,8 +830,21 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
>   	}
>   #endif
>   
> -	if (amdgpu_sync_init(pScreen))
> -		amdgpu_present_screen_init(pScreen);
> +	value = FALSE;
> +	if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value))
> +		from = X_CONFIG;
> +	else
> +		from = X_DEFAULT;
> +
> +	if (value) {
> +		value = amdgpu_sync_init(pScreen) &&
> +			amdgpu_present_screen_init(pScreen) &&
> +			amdgpu_dri3_screen_init(pScreen);
> +
> +		if (!value)
> +			from = X_WARNING;
> +	}
> +	xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis");
Hmmm, wouldn't be more human-readable to write it as
xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %s\n", value ? "enabled" : 
"disabled");
?
What the profit of such an "optimization"?

>   
>   	pScrn->vtSema = TRUE;
>   	xf86SetBackingStore(pScreen);

-- 
--
Regards,
R.H.



More information about the xorg-driver-ati mailing list