mirror of
https://github.com/X11Libre/xf86-video-ati.git
synced 2026-03-24 01:24:43 +00:00
Add DRI3 support v2
Must be enabled with Option "DRI3" in xorg.conf. v2: Adapt to v2 of patches 11/12. Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Michel Dänzer
parent
69ae019477
commit
64e1e4dbdd
@@ -143,6 +143,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])
|
||||
|
||||
@@ -267,6 +267,10 @@ The default value is
|
||||
for R/RV6XX, R/RV7XX, RS780, RS880, EVERGREEN, CAYMAN, ARUBA, Southern Islands, and
|
||||
Sea Islands.
|
||||
.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.
|
||||
|
||||
@@ -29,8 +29,9 @@
|
||||
ati_drv_la_LIBADD = $(PCIACCESS_LIBS)
|
||||
radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS) $(PCIACCESS_LIBS)
|
||||
|
||||
RADEON_KMS_SRCS=radeon_dri2.c radeon_drm_queue.c radeon_kms.c radeon_present.c \
|
||||
radeon_sync.c radeon_vbo.c radeon_bo_helper.c drmmode_display.c
|
||||
RADEON_KMS_SRCS=radeon_dri2.c radeon_dri3.c radeon_drm_queue.c radeon_kms.c \
|
||||
radeon_present.c radeon_sync.c radeon_vbo.c radeon_bo_helper.c \
|
||||
drmmode_display.c
|
||||
|
||||
RADEON_EXA_SOURCES = radeon_exa.c r600_exa.c r6xx_accel.c r600_textured_videofuncs.c r600_shader.c radeon_exa_shared.c \
|
||||
evergreen_exa.c evergreen_accel.c evergreen_shader.c evergreen_textured_videofuncs.c cayman_accel.c cayman_shader.c
|
||||
|
||||
@@ -150,6 +150,7 @@ typedef enum {
|
||||
OPTION_ZAPHOD_HEADS,
|
||||
OPTION_SWAPBUFFERS_WAIT,
|
||||
OPTION_DELETE_DP12,
|
||||
OPTION_DRI3,
|
||||
} RADEONOpts;
|
||||
|
||||
|
||||
@@ -549,6 +550,9 @@ extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
|
||||
extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
|
||||
uint32_t *pitch_offset);
|
||||
|
||||
/* radeon_dri3.c */
|
||||
Bool radeon_dri3_screen_init(ScreenPtr screen);
|
||||
|
||||
/* radeon_present.c */
|
||||
Bool radeon_present_screen_init(ScreenPtr screen);
|
||||
|
||||
|
||||
201
src/radeon_dri3.c
Normal file
201
src/radeon_dri3.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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 "xorg-server.h"
|
||||
#include "xf86.h"
|
||||
#include "fb.h"
|
||||
|
||||
#ifdef HAVE_DRI3_H
|
||||
|
||||
#include "radeon.h"
|
||||
#include "radeon_bo_gem.h"
|
||||
#include "radeon_glamor.h"
|
||||
#include "dri3.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
static int
|
||||
radeon_dri3_open_client(ClientPtr client,
|
||||
ScreenPtr screen,
|
||||
RRProviderPtr provider,
|
||||
int *out)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
RADEONInfoPtr info = RADEONPTR(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 radeon_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 = fbCreatePixmap(screen, 0, 0, depth, 0);
|
||||
if (!pixmap)
|
||||
return NULL;
|
||||
|
||||
if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL))
|
||||
goto free_pixmap;
|
||||
|
||||
if (screen->SetSharedPixmapBacking(pixmap, (void*)(intptr_t)fd))
|
||||
return pixmap;
|
||||
|
||||
free_pixmap:
|
||||
fbDestroyPixmap(pixmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int radeon_dri3_fd_from_pixmap(ScreenPtr screen,
|
||||
PixmapPtr pixmap,
|
||||
CARD16 *stride,
|
||||
CARD32 *size)
|
||||
{
|
||||
struct radeon_bo *bo;
|
||||
int fd;
|
||||
|
||||
bo = radeon_get_pixmap_bo(pixmap);
|
||||
if (!bo) {
|
||||
#ifdef USE_GLAMOR
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
|
||||
if (info->use_glamor)
|
||||
return glamor_fd_from_pixmap(screen, pixmap, stride, size);
|
||||
#endif
|
||||
|
||||
exaMoveInPixmap(pixmap);
|
||||
bo = radeon_get_pixmap_bo(pixmap);
|
||||
if (!bo)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pixmap->devKind > UINT16_MAX)
|
||||
return -1;
|
||||
|
||||
if (radeon_gem_prime_share_bo(bo, &fd) < 0)
|
||||
return -1;
|
||||
|
||||
*stride = pixmap->devKind;
|
||||
*size = bo->size;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static dri3_screen_info_rec radeon_dri3_screen_info = {
|
||||
.version = 1,
|
||||
|
||||
.open_client = radeon_dri3_open_client,
|
||||
.pixmap_from_fd = radeon_dri3_pixmap_from_fd,
|
||||
.fd_from_pixmap = radeon_dri3_fd_from_pixmap
|
||||
};
|
||||
|
||||
Bool
|
||||
radeon_dri3_screen_init(ScreenPtr screen)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
|
||||
if (!dri3_screen_init(screen, &radeon_dri3_screen_info)) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
"dri3_screen_init failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* !HAVE_DRI3_H */
|
||||
|
||||
Bool
|
||||
radeon_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
|
||||
@@ -76,6 +76,7 @@ const OptionInfoRec RADEONOptions_KMS[] = {
|
||||
{ OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE },
|
||||
{ OPTION_SWAPBUFFERS_WAIT,"SwapbuffersWait", OPTV_BOOLEAN, {0}, FALSE },
|
||||
{ OPTION_DELETE_DP12, "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{ OPTION_DRI3, "DRI3", OPTV_BOOLEAN, {0}, FALSE },
|
||||
{ -1, NULL, OPTV_NONE, {0}, FALSE }
|
||||
};
|
||||
|
||||
@@ -1230,6 +1231,8 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
|
||||
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
int subPixelOrder = SubPixelUnknown;
|
||||
MessageType from;
|
||||
Bool have_present = FALSE, value;
|
||||
const char *s;
|
||||
void *front_ptr;
|
||||
|
||||
@@ -1341,7 +1344,23 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
|
||||
#endif
|
||||
|
||||
if (radeon_sync_init(pScreen))
|
||||
radeon_present_screen_init(pScreen);
|
||||
have_present = radeon_present_screen_init(pScreen);
|
||||
|
||||
if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value))
|
||||
from = X_CONFIG;
|
||||
else
|
||||
from = X_DEFAULT;
|
||||
|
||||
if (value) {
|
||||
if (have_present)
|
||||
value = radeon_dri3_screen_init(pScreen);
|
||||
else
|
||||
value = FALSE;
|
||||
|
||||
if (!value)
|
||||
from = X_WARNING;
|
||||
}
|
||||
xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis");
|
||||
|
||||
pScrn->vtSema = TRUE;
|
||||
xf86SetBackingStore(pScreen);
|
||||
|
||||
Reference in New Issue
Block a user