Initial glamor support.

Enable at build time with --enable-glamor and runtime with

	Option	"AccelMethod" "glamor"

The most notable lack of functionality is XVideo. Use something like VDPAU for
now.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
Michel Dänzer
2012-06-20 08:40:07 +02:00
committed by Michel Dänzer
parent 9eac8021f3
commit e9edd2f500
11 changed files with 711 additions and 143 deletions

View File

@@ -91,6 +91,20 @@ AM_CONDITIONAL(LIBUDEV, test x$LIBUDEV = xyes)
SAVE_CPPFLAGS="$CPPFLAGS" SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $XORG_CFLAGS" CPPFLAGS="$CPPFLAGS $XORG_CFLAGS"
AC_MSG_CHECKING([whether to include GLAMOR support])
AC_ARG_ENABLE(glamor,
AS_HELP_STRING([--enable-glamor],
[Enable glamor, a new GL-based acceleration [default=no]]),
[GLAMOR="$enableval"],
[GLAMOR=no])
AC_MSG_RESULT([$GLAMOR])
AM_CONDITIONAL(GLAMOR, test x$GLAMOR != xno)
if test "x$GLAMOR" != "xno"; then
PKG_CHECK_MODULES(LIBGLAMOR, [glamor >= 0.3.1])
PKG_CHECK_MODULES(LIBGLAMOR_EGL, [glamor-egl])
AC_DEFINE(USE_GLAMOR, 1, [Enable glamor acceleration])
fi
AC_CHECK_DECL(xf86ModeBandwidth, AC_CHECK_DECL(xf86ModeBandwidth,
[AC_DEFINE(HAVE_XF86MODEBANDWIDTH, 1, [Have xf86ModeBandwidth prototype])], [AC_DEFINE(HAVE_XF86MODEBANDWIDTH, 1, [Have xf86ModeBandwidth prototype])],
[], [],

View File

@@ -211,13 +211,6 @@ For example:
Option \*qZaphodHeads\*q \*qLVDS,VGA-0\*q Option \*qZaphodHeads\*q \*qLVDS,VGA-0\*q
will assign xrandr outputs LVDS and VGA-0 to this instance of the driver. will assign xrandr outputs LVDS and VGA-0 to this instance of the driver.
.TP .TP
.BI "Option \*qEXAVSync\*q \*q" boolean \*q
This option attempts to avoid tearing by stalling the engine until the display
controller has passed the destination region. It reduces tearing at the cost
of performance and has been known to cause instability on some chips.
The default is
.B off.
.TP
.BI "Option \*qColorTiling\*q \*q" "boolean" \*q .BI "Option \*qColorTiling\*q \*q" "boolean" \*q
The framebuffer can be addressed either in linear or tiled mode. Tiled mode can provide The framebuffer can be addressed either in linear or tiled mode. Tiled mode can provide
significant performance benefits with 3D applications. Tiling will be disabled if the drm significant performance benefits with 3D applications. Tiling will be disabled if the drm
@@ -241,6 +234,33 @@ The default value is
.B off .B off
for R/RV6XX, R/RV7XX, RS780, RS880, EVERGREEN, and CAYMAN. for R/RV6XX, R/RV7XX, RS780, RS880, EVERGREEN, and CAYMAN.
.TP .TP
.BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
Enable DRI2 page flipping. The default is
.B on.
Pageflipping is supported on all radeon hardware.
.TP
.BI "Option \*qAccelMethod\*q \*q" "string" \*q
Chooses between available acceleration architectures. Valid values are
.B EXA
and
.B glamor.
The default is
.B EXA.
.PP
The following driver
.B Options
are supported for
.B EXA
:
.TP
.BI "Option \*qEXAVSync\*q \*q" boolean \*q
This option attempts to avoid tearing by stalling the engine until the display
controller has passed the destination region. It reduces tearing at the cost
of performance and has been known to cause instability on some chips.
The default is
.B off.
.TP
.BI "Option \*qEXAPixmaps\*q \*q" boolean \*q .BI "Option \*qEXAPixmaps\*q \*q" boolean \*q
Under KMS, to avoid thrashing pixmaps in/out of VRAM on low memory cards, Under KMS, to avoid thrashing pixmaps in/out of VRAM on low memory cards,
we use a heuristic based on VRAM amount to determine whether to allow EXA we use a heuristic based on VRAM amount to determine whether to allow EXA
@@ -259,11 +279,6 @@ the framerate of applications that render frames at less than refresh rate.
.IP .IP
The default value is The default value is
.B on. .B on.
.TP
.BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
Enable DRI2 page flipping. The default is
.B on.
Pageflipping is supported on all radeon hardware.
.SH TEXTURED VIDEO ATTRIBUTES .SH TEXTURED VIDEO ATTRIBUTES
The driver supports the following X11 Xv attributes for Textured Video. The driver supports the following X11 Xv attributes for Textured Video.

View File

@@ -64,6 +64,13 @@ radeon_drv_la_SOURCES = \
$(RADEON_EXA_SOURCES) \ $(RADEON_EXA_SOURCES) \
$(RADEON_KMS_SRCS) $(RADEON_KMS_SRCS)
if GLAMOR
AM_CFLAGS += @LIBGLAMOR_CFLAGS@
radeon_drv_la_LIBADD += @LIBGLAMOR_LIBS@
radeon_drv_la_SOURCES += \
radeon_glamor.c
endif
EXTRA_DIST = \ EXTRA_DIST = \
radeon_textured_videofuncs.c \ radeon_textured_videofuncs.c \
r600_reg.h \ r600_reg.h \
@@ -88,6 +95,7 @@ EXTRA_DIST = \
radeon_exa_render.c \ radeon_exa_render.c \
radeon_exa_funcs.c \ radeon_exa_funcs.c \
radeon_exa_shared.h \ radeon_exa_shared.h \
radeon_glamor.h \
radeon.h \ radeon.h \
radeon_probe.h \ radeon_probe.h \
radeon_reg.h \ radeon_reg.h \

View File

@@ -101,7 +101,8 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn,
return NULL; return NULL;
} }
exaMoveInPixmap(pixmap); if (!info->use_glamor)
exaMoveInPixmap(pixmap);
radeon_set_pixmap_bo(pixmap, bo); radeon_set_pixmap_bo(pixmap, bo);
if (info->ChipFamily >= CHIP_FAMILY_R600) { if (info->ChipFamily >= CHIP_FAMILY_R600) {
surface = radeon_get_pixmap_surface(pixmap); surface = radeon_get_pixmap_surface(pixmap);
@@ -278,7 +279,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
uint32_t tiling_flags = 0; uint32_t tiling_flags = 0;
Bool ret; Bool ret;
if (info->accelOn == FALSE) if (info->accelOn == FALSE || info->use_glamor)
goto fallback; goto fallback;
for (i = 0; i < xf86_config->num_crtc; i++) { for (i = 0; i < xf86_config->num_crtc; i++) {
@@ -1442,6 +1443,9 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
crtc->rotation, crtc->x, crtc->y); crtc->rotation, crtc->x, crtc->y);
} }
if (info->use_glamor)
radeon_glamor_create_screen_resources(scrn->pScreen);
if (old_fb_id) if (old_fb_id)
drmModeRmFB(drmmode->fd, old_fb_id); drmModeRmFB(drmmode->fd, old_fb_id);
if (old_front) if (old_front)

View File

@@ -51,6 +51,7 @@
#include "exa.h" #include "exa.h"
#include "radeon_glamor.h"
/* Exa and Cursor Support */ /* Exa and Cursor Support */
#include "xf86Cursor.h" #include "xf86Cursor.h"
@@ -429,6 +430,7 @@ typedef struct {
Bool allowColorTiling2D; Bool allowColorTiling2D;
struct radeon_accel_state *accel_state; struct radeon_accel_state *accel_state;
Bool accelOn; Bool accelOn;
Bool use_glamor;
Bool exa_pixmaps; Bool exa_pixmaps;
Bool exa_force_create; Bool exa_force_create;
XF86ModReqInfo exaReq; XF86ModReqInfo exaReq;
@@ -522,11 +524,107 @@ extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
int num, const char *file, int num, const char *file,
const char *func, int line); const char *func, int line);
void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size); void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size);
struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix);
struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix); static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo); {
#ifdef USE_GLAMOR
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
if (info->use_glamor) {
struct radeon_pixmap *priv;
priv = radeon_get_pixmap_private(pPix);
return priv ? &priv->surface : NULL;
} else
#endif
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(pPix);
return &driver_priv->surface;
}
return NULL;
}
uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix); uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix);
static inline void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
{
#ifdef USE_GLAMOR
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
if (info->use_glamor) {
struct radeon_pixmap *priv;
priv = radeon_get_pixmap_private(pPix);
if (priv == NULL && bo == NULL)
return;
if (priv) {
if (priv->bo == bo)
return;
if (priv->bo)
radeon_bo_unref(priv->bo);
free(priv);
priv = NULL;
}
if (bo) {
uint32_t pitch;
priv = calloc(1, sizeof (struct radeon_pixmap));
if (priv == NULL)
goto out;
radeon_bo_ref(bo);
priv->bo = bo;
radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch);
}
out:
radeon_set_pixmap_private(pPix, priv);
} else
#endif /* USE_GLAMOR */
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(pPix);
if (driver_priv) {
uint32_t pitch;
if (driver_priv->bo)
radeon_bo_unref(driver_priv->bo);
radeon_bo_ref(bo);
driver_priv->bo = bo;
radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch);
}
}
}
static inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
{
#ifdef USE_GLAMOR
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
if (info->use_glamor) {
struct radeon_pixmap *priv;
priv = radeon_get_pixmap_private(pPix);
return priv ? priv->bo : NULL;
} else
#endif
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(pPix);
return driver_priv->bo;
}
return NULL;
}
#define CP_PACKET0(reg, n) \ #define CP_PACKET0(reg, n) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET1(reg0, reg1) \ #define CP_PACKET1(reg0, reg1) \
@@ -659,6 +757,7 @@ static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn)
} }
enum { enum {
RADEON_CREATE_PIXMAP_DRI2 = 0x08000000,
RADEON_CREATE_PIXMAP_TILING_MACRO = 0x10000000, RADEON_CREATE_PIXMAP_TILING_MACRO = 0x10000000,
RADEON_CREATE_PIXMAP_TILING_MICRO = 0x20000000, RADEON_CREATE_PIXMAP_TILING_MICRO = 0x20000000,
RADEON_CREATE_PIXMAP_DEPTH = 0x40000000, /* for r200 */ RADEON_CREATE_PIXMAP_DEPTH = 0x40000000, /* for r200 */

View File

@@ -182,7 +182,12 @@ Bool RADEONAccelInit(ScreenPtr pScreen)
RADEONInfoPtr info = RADEONPTR(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn);
if (info->directRenderingEnabled) { if (info->directRenderingEnabled) {
if (info->ChipFamily >= CHIP_FAMILY_CEDAR) { if (info->use_glamor) {
if (!radeon_glamor_init(pScreen)) {
info->use_glamor = FALSE;
return FALSE;
}
} else if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
if (!EVERGREENDrawInit(pScreen)) if (!EVERGREENDrawInit(pScreen))
return FALSE; return FALSE;
} else } else

View File

@@ -73,6 +73,77 @@ struct dri2_buffer_priv {
}; };
static PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
{
if (drawable->type == DRAWABLE_PIXMAP)
return (PixmapPtr)drawable;
else
return (*drawable->pScreen->GetWindowPixmap)((WindowPtr)drawable);
}
static PixmapPtr fixup_glamor(DrawablePtr drawable, PixmapPtr pixmap)
{
PixmapPtr old = get_drawable_pixmap(drawable);
#ifdef USE_GLAMOR
ScreenPtr screen = drawable->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
GCPtr gc;
/* With a glamor pixmap, 2D pixmaps are created in texture
* and without a static BO attached to it. To support DRI,
* we need to create a new textured-drm pixmap and
* need to copy the original content to this new textured-drm
* pixmap, and then convert the old pixmap to a coherent
* textured-drm pixmap which has a valid BO attached to it
* and also has a valid texture, thus both glamor and DRI2
* can access it.
*
*/
/* Copy the current contents of the pixmap to the bo. */
gc = GetScratchGC(drawable->depth, screen);
if (gc) {
ValidateGC(&pixmap->drawable, gc);
gc->ops->CopyArea(&old->drawable, &pixmap->drawable,
gc,
0, 0,
old->drawable.width,
old->drawable.height,
0, 0);
FreeScratchGC(gc);
}
radeon_set_pixmap_private(pixmap, NULL);
screen->DestroyPixmap(pixmap);
/* And redirect the pixmap to the new bo (for 3D). */
radeon_set_pixmap_private(old, priv);
old->refcnt++;
/* This creating should not fail, as we already created its
* successfully. But if it happens, we put a warning indicator
* here, and the old pixmap will still be a glamor pixmap, and
* latter the pixmap_flink will get a 0 name, then the X server
* will pass a BadAlloc to the client.*/
if (!radeon_glamor_create_textured_pixmap(old))
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Failed to get DRI drawable for glamor pixmap.\n");
screen->ModifyPixmapHeader(old,
old->drawable.width,
old->drawable.height,
0, 0,
priv->stride,
NULL);
#endif /* USE_GLAMOR*/
return old;
}
#ifndef USE_DRI2_1_1_0 #ifndef USE_DRI2_1_1_0
static BufferPtr static BufferPtr
radeon_dri2_create_buffers(DrawablePtr drawable, radeon_dri2_create_buffers(DrawablePtr drawable,
@@ -85,13 +156,13 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
BufferPtr buffers; BufferPtr buffers;
struct dri2_buffer_priv *privates; struct dri2_buffer_priv *privates;
PixmapPtr pixmap, depth_pixmap; PixmapPtr pixmap, depth_pixmap;
struct radeon_exa_pixmap_priv *driver_priv; struct radeon_bo *bo;
int i, r, need_enlarge = 0; int i, r, need_enlarge = 0;
int flags = 0; int flags = 0;
unsigned front_width; unsigned front_width;
uint32_t tiling = 0; uint32_t tiling = 0;
pixmap = screen->GetScreenPixmap(screen); pixmap = pScreen->GetScreenPixmap(pScreen);
front_width = pixmap->drawable.width; front_width = pixmap->drawable.width;
buffers = calloc(count, sizeof *buffers); buffers = calloc(count, sizeof *buffers);
@@ -106,17 +177,25 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
depth_pixmap = NULL; depth_pixmap = NULL;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
Bool is_glamor_pixmap = FALSE;
unsigned aligned_width = drawable->width;
unsigned aligned_height = drawable->height;
if (attachments[i] == DRI2BufferFrontLeft) { if (attachments[i] == DRI2BufferFrontLeft) {
if (drawable->type == DRAWABLE_PIXMAP) { pixmap = get_drawable_pixmap(drawable);
pixmap = (Pixmap*)drawable; if (info->use_glamor && !radeon_get_pixmap_bo(pixmap)) {
} else { is_glamor_pixmap = TRUE;
pixmap = (*pScreen->GetWindowPixmap)((WindowPtr)drawable); aligned_width = pixmap->drawable.width;
} aligned_height = pixmap->drawable.height;
pixmap->refcnt++; pixmap = NULL;
} else
pixmap->refcnt++;
} else if (attachments[i] == DRI2BufferStencil && depth_pixmap) { } else if (attachments[i] == DRI2BufferStencil && depth_pixmap) {
pixmap = depth_pixmap; pixmap = depth_pixmap;
pixmap->refcnt++; pixmap->refcnt++;
} else { }
if (!pixmap) {
/* tile the back buffer */ /* tile the back buffer */
switch(attachments[i]) { switch(attachments[i]) {
case DRI2BufferDepth: case DRI2BufferDepth:
@@ -145,6 +224,8 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
break; break;
case DRI2BufferBackLeft: case DRI2BufferBackLeft:
case DRI2BufferBackRight: case DRI2BufferBackRight:
case DRI2BufferFrontLeft:
case DRI2BufferFrontRight:
case DRI2BufferFakeFrontLeft: case DRI2BufferFakeFrontLeft:
case DRI2BufferFakeFrontRight: case DRI2BufferFakeFrontRight:
if (info->ChipFamily >= CHIP_FAMILY_R600) if (info->ChipFamily >= CHIP_FAMILY_R600)
@@ -164,14 +245,15 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
if (flags & RADEON_CREATE_PIXMAP_TILING_MACRO) if (flags & RADEON_CREATE_PIXMAP_TILING_MACRO)
tiling |= RADEON_TILING_MACRO; tiling |= RADEON_TILING_MACRO;
if (aligned_width == front_width)
aligned_width = pScrn->virtualX;
if (need_enlarge) { if (need_enlarge) {
/* evergreen uses separate allocations for depth and stencil /* evergreen uses separate allocations for depth and stencil
* so we make an extra large depth buffer to cover stencil * so we make an extra large depth buffer to cover stencil
* as well. * as well.
*/ */
unsigned aligned_width = drawable->width;
unsigned width_align = drmmode_get_pitch_align(pScrn, drawable->depth / 8, tiling); unsigned width_align = drmmode_get_pitch_align(pScrn, drawable->depth / 8, tiling);
unsigned aligned_height;
unsigned height_align = drmmode_get_height_align(pScrn, tiling); unsigned height_align = drmmode_get_height_align(pScrn, tiling);
unsigned base_align = drmmode_get_base_align(pScrn, drawable->depth / 8, tiling); unsigned base_align = drmmode_get_base_align(pScrn, drawable->depth / 8, tiling);
unsigned pitch_bytes; unsigned pitch_bytes;
@@ -181,42 +263,33 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
aligned_width = pScrn->virtualX; aligned_width = pScrn->virtualX;
aligned_width = RADEON_ALIGN(aligned_width, width_align); aligned_width = RADEON_ALIGN(aligned_width, width_align);
pitch_bytes = aligned_width * (drawable->depth / 8); pitch_bytes = aligned_width * (drawable->depth / 8);
aligned_height = RADEON_ALIGN(drawable->height, height_align); aligned_height = RADEON_ALIGN(aligned_height, height_align);
size = pitch_bytes * aligned_height; size = pitch_bytes * aligned_height;
size = RADEON_ALIGN(size, base_align); size = RADEON_ALIGN(size, base_align);
/* add additional size for stencil */ /* add additional size for stencil */
size += aligned_width * aligned_height; size += aligned_width * aligned_height;
aligned_height = RADEON_ALIGN(size / pitch_bytes, height_align); aligned_height = RADEON_ALIGN(size / pitch_bytes, height_align);
pixmap = (*pScreen->CreatePixmap)(pScreen,
aligned_width,
aligned_height,
drawable->depth,
flags);
} else {
unsigned aligned_width = drawable->width;
if (aligned_width == front_width)
aligned_width = pScrn->virtualX;
pixmap = (*pScreen->CreatePixmap)(pScreen,
aligned_width,
drawable->height,
drawable->depth,
flags);
} }
pixmap = (*pScreen->CreatePixmap)(pScreen,
aligned_width,
aligned_height,
drawable->depth,
flags | RADEON_CREATE_PIXMAP_DRI2);
} }
if (attachments[i] == DRI2BufferDepth) { if (attachments[i] == DRI2BufferDepth) {
depth_pixmap = pixmap; depth_pixmap = pixmap;
} }
info->exa_force_create = TRUE; if (!info->use_glamor) {
exaMoveInPixmap(pixmap); info->exa_force_create = TRUE;
info->exa_force_create = FALSE; exaMoveInPixmap(pixmap);
driver_priv = exaGetPixmapDriverPrivate(pixmap); info->exa_force_create = FALSE;
if (!driver_priv || }
radeon_gem_get_kernel_name(driver_priv->bo, &buffers[i].name) != 0) { if (is_glamor_pixmap)
pixmap = fixup_glamor(drawable, pixmap);
bo = radeon_get_pixmap_bo(pixmap);
if (!bo || radeon_gem_get_kernel_name(bo, &buffers[i].name) != 0) {
int j; int j;
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
@@ -249,11 +322,13 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
BufferPtr buffers; BufferPtr buffers;
struct dri2_buffer_priv *privates; struct dri2_buffer_priv *privates;
PixmapPtr pixmap, depth_pixmap; PixmapPtr pixmap, depth_pixmap;
struct radeon_exa_pixmap_priv *driver_priv; struct radeon_bo *bo;
int flags; int flags;
unsigned front_width; unsigned front_width;
uint32_t tiling = 0; uint32_t tiling = 0;
unsigned aligned_width = drawable->width; unsigned aligned_width = drawable->width;
unsigned height = drawable->height;
Bool is_glamor_pixmap = FALSE;
pixmap = pScreen->GetScreenPixmap(pScreen); pixmap = pScreen->GetScreenPixmap(pScreen);
front_width = pixmap->drawable.width; front_width = pixmap->drawable.width;
@@ -261,16 +336,20 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
pixmap = depth_pixmap = NULL; pixmap = depth_pixmap = NULL;
if (attachment == DRI2BufferFrontLeft) { if (attachment == DRI2BufferFrontLeft) {
if (drawable->type == DRAWABLE_PIXMAP) { pixmap = get_drawable_pixmap(drawable);
pixmap = (PixmapPtr)drawable; if (info->use_glamor && !radeon_get_pixmap_bo(pixmap)) {
} else { is_glamor_pixmap = TRUE;
pixmap = (*pScreen->GetWindowPixmap)((WindowPtr)drawable); aligned_width = pixmap->drawable.width;
} height = pixmap->drawable.height;
pixmap->refcnt++; pixmap = NULL;
} else
pixmap->refcnt++;
} else if (attachment == DRI2BufferStencil && depth_pixmap) { } else if (attachment == DRI2BufferStencil && depth_pixmap) {
pixmap = depth_pixmap; pixmap = depth_pixmap;
pixmap->refcnt++; pixmap->refcnt++;
} else { }
if (!pixmap) {
/* tile the back buffer */ /* tile the back buffer */
switch(attachment) { switch(attachment) {
case DRI2BufferDepth: case DRI2BufferDepth:
@@ -310,6 +389,8 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
break; break;
case DRI2BufferBackLeft: case DRI2BufferBackLeft:
case DRI2BufferBackRight: case DRI2BufferBackRight:
case DRI2BufferFrontLeft:
case DRI2BufferFrontRight:
case DRI2BufferFakeFrontLeft: case DRI2BufferFakeFrontLeft:
case DRI2BufferFakeFrontRight: case DRI2BufferFakeFrontRight:
if (info->ChipFamily >= CHIP_FAMILY_R600) { if (info->ChipFamily >= CHIP_FAMILY_R600) {
@@ -336,9 +417,9 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
pixmap = (*pScreen->CreatePixmap)(pScreen, pixmap = (*pScreen->CreatePixmap)(pScreen,
aligned_width, aligned_width,
drawable->height, height,
(format != 0)?format:drawable->depth, (format != 0)?format:drawable->depth,
flags); flags | RADEON_CREATE_PIXMAP_DRI2);
} }
if (!pixmap) if (!pixmap)
@@ -351,12 +432,15 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
if (attachment == DRI2BufferDepth) { if (attachment == DRI2BufferDepth) {
depth_pixmap = pixmap; depth_pixmap = pixmap;
} }
info->exa_force_create = TRUE; if (!info->use_glamor) {
exaMoveInPixmap(pixmap); info->exa_force_create = TRUE;
info->exa_force_create = FALSE; exaMoveInPixmap(pixmap);
driver_priv = exaGetPixmapDriverPrivate(pixmap); info->exa_force_create = FALSE;
if (!driver_priv || }
(radeon_gem_get_kernel_name(driver_priv->bo, &buffers->name) != 0)) if (is_glamor_pixmap)
pixmap = fixup_glamor(drawable, pixmap);
bo = radeon_get_pixmap_bo(pixmap);
if (!bo || radeon_gem_get_kernel_name(bo, &buffers->name) != 0)
goto error; goto error;
privates = calloc(1, sizeof(struct dri2_buffer_priv)); privates = calloc(1, sizeof(struct dri2_buffer_priv));
@@ -476,11 +560,10 @@ radeon_dri2_copy_region(DrawablePtr drawable,
if (extents->x1 == 0 && extents->y1 == 0 && if (extents->x1 == 0 && extents->y1 == 0 &&
extents->x2 == drawable->width && extents->x2 == drawable->width &&
extents->y2 == drawable->height) { extents->y2 == drawable->height) {
struct radeon_exa_pixmap_priv *exa_priv = struct radeon_bo *bo = radeon_get_pixmap_bo(dst_private->pixmap);
exaGetPixmapDriverPrivate(dst_private->pixmap);
if (exa_priv && exa_priv->bo) if (bo)
radeon_bo_wait(exa_priv->bo); radeon_bo_wait(bo);
} }
} }
} }
@@ -643,7 +726,7 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
void *data, unsigned int target_msc) void *data, unsigned int target_msc)
{ {
struct dri2_buffer_priv *back_priv; struct dri2_buffer_priv *back_priv;
struct radeon_exa_pixmap_priv *exa_priv; struct radeon_bo *bo;
DRI2FrameEventPtr flip_info; DRI2FrameEventPtr flip_info;
/* Main crtc for this drawable shall finally deliver pageflip event. */ /* Main crtc for this drawable shall finally deliver pageflip event. */
@@ -665,9 +748,9 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
/* Page flip the full screen buffer */ /* Page flip the full screen buffer */
back_priv = back->driverPrivate; back_priv = back->driverPrivate;
exa_priv = exaGetPixmapDriverPrivate(back_priv->pixmap); bo = radeon_get_pixmap_bo(back_priv->pixmap);
return radeon_do_pageflip(scrn, exa_priv->bo, flip_info, ref_crtc_hw_id); return radeon_do_pageflip(scrn, bo, flip_info, ref_crtc_hw_id);
} }
static Bool static Bool
@@ -675,19 +758,17 @@ update_front(DrawablePtr draw, DRI2BufferPtr front)
{ {
int r; int r;
PixmapPtr pixmap; PixmapPtr pixmap;
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(draw->pScreen));
struct dri2_buffer_priv *priv = front->driverPrivate; struct dri2_buffer_priv *priv = front->driverPrivate;
struct radeon_exa_pixmap_priv *driver_priv; struct radeon_bo *bo;
if (draw->type == DRAWABLE_PIXMAP)
pixmap = (PixmapPtr)draw;
else
pixmap = (*draw->pScreen->GetWindowPixmap)((WindowPtr)draw);
pixmap = get_drawable_pixmap(draw);
pixmap->refcnt++; pixmap->refcnt++;
exaMoveInPixmap(pixmap); if (!info->use_glamor)
driver_priv = exaGetPixmapDriverPrivate(pixmap); exaMoveInPixmap(pixmap);
r = radeon_gem_get_kernel_name(driver_priv->bo, &front->name); bo = radeon_get_pixmap_bo(pixmap);
r = radeon_gem_get_kernel_name(bo, &front->name);
if (r) { if (r) {
(*draw->pScreen->DestroyPixmap)(pixmap); (*draw->pScreen->DestroyPixmap)(pixmap);
return FALSE; return FALSE;
@@ -753,10 +834,9 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt
{ {
struct dri2_buffer_priv *front_priv = front->driverPrivate; struct dri2_buffer_priv *front_priv = front->driverPrivate;
struct dri2_buffer_priv *back_priv = back->driverPrivate; struct dri2_buffer_priv *back_priv = back->driverPrivate;
struct radeon_exa_pixmap_priv *front_radeon, *back_radeon; struct radeon_bo *front_bo, *back_bo;
ScreenPtr screen; ScreenPtr screen;
RADEONInfoPtr info; RADEONInfoPtr info;
struct radeon_bo *bo;
int tmp; int tmp;
/* Swap BO names so DRI works */ /* Swap BO names so DRI works */
@@ -765,22 +845,22 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt
back->name = tmp; back->name = tmp;
/* Swap pixmap bos */ /* Swap pixmap bos */
front_radeon = exaGetPixmapDriverPrivate(front_priv->pixmap); front_bo = radeon_get_pixmap_bo(front_priv->pixmap);
back_radeon = exaGetPixmapDriverPrivate(back_priv->pixmap); back_bo = radeon_get_pixmap_bo(back_priv->pixmap);
bo = back_radeon->bo; radeon_set_pixmap_bo(front_priv->pixmap, back_bo);
back_radeon->bo = front_radeon->bo; radeon_set_pixmap_bo(back_priv->pixmap, front_bo);
front_radeon->bo = bo;
/* Do we need to update the Screen? */ /* Do we need to update the Screen? */
screen = draw->pScreen; screen = draw->pScreen;
info = RADEONPTR(xf86ScreenToScrn(screen)); info = RADEONPTR(xf86ScreenToScrn(screen));
if (front_radeon->bo == info->front_bo) { if (front_bo == info->front_bo) {
radeon_bo_ref(back_bo);
radeon_bo_unref(info->front_bo); radeon_bo_unref(info->front_bo);
info->front_bo = back_radeon->bo; info->front_bo = back_bo;
radeon_bo_ref(info->front_bo); radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), back_bo);
front_radeon = exaGetPixmapDriverPrivate(screen->GetScreenPixmap(screen));
front_radeon->bo = bo;
} }
radeon_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap);
} }
void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,

View File

@@ -325,20 +325,6 @@ void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv)
free(driverPriv); free(driverPriv);
} }
struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(pPix);
return driver_priv->bo;
}
struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(pPix);
return &driver_priv->surface;
}
uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix) uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix)
{ {
struct radeon_exa_pixmap_priv *driver_priv; struct radeon_exa_pixmap_priv *driver_priv;
@@ -346,24 +332,6 @@ uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix)
return driver_priv->tiling_flags; return driver_priv->tiling_flags;
} }
void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(pPix);
if (driver_priv) {
uint32_t pitch;
if (driver_priv->bo)
radeon_bo_unref(driver_priv->bo);
radeon_bo_ref(bo);
driver_priv->bo = bo;
radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch);
}
}
Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix) Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix)
{ {
struct radeon_exa_pixmap_priv *driver_priv; struct radeon_exa_pixmap_priv *driver_priv;

269
src/radeon_glamor.c Normal file
View File

@@ -0,0 +1,269 @@
/*
* Copyright © 2011 Intel Corporation.
* 2012 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including
* the next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <xf86.h>
#define GLAMOR_FOR_XORG 1
#include <glamor.h>
#include "radeon.h"
#include "radeon_bo_helper.h"
#if HAS_DEVPRIVATEKEYREC
DevPrivateKeyRec glamor_pixmap_index;
#else
int glamor_pixmap_index;
#endif
void
radeon_glamor_exchange_buffers(PixmapPtr src,
PixmapPtr dst)
{
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(dst->drawable.pScreen));
if (!info->use_glamor)
return;
glamor_egl_exchange_buffers(src, dst);
}
Bool
radeon_glamor_create_screen_resources(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
if (!info->use_glamor)
return TRUE;
if (!glamor_glyphs_init(screen))
return FALSE;
if (!glamor_egl_create_textured_screen_ext(screen,
info->front_bo->handle,
scrn->displayWidth *
info->pixel_bytes,
NULL))
return FALSE;
return TRUE;
}
Bool
radeon_glamor_pre_init(ScrnInfoPtr scrn)
{
RADEONInfoPtr info = RADEONPTR(scrn);
pointer glamor_module;
CARD32 version;
const char *s;
s = xf86GetOptValString(info->Options, OPTION_ACCELMETHOD);
if (s == NULL)
return FALSE;
if (strcasecmp(s, "glamor") != 0)
return FALSE;
/* Load glamor module */
if ((glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME))) {
version = xf86GetModuleVersion(glamor_module);
if (version < MODULE_VERSION_NUMERIC(0,3,1)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Incompatible glamor version, required >= 0.3.0.\n");
return FALSE;
} else {
if (glamor_egl_init(scrn, info->dri2.drm_fd)) {
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"glamor detected, initialising EGL layer.\n");
} else {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"glamor detected, failed to initialize EGL.\n");
return FALSE;
}
}
} else {
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "glamor not available\n");
return FALSE;
}
info->use_glamor = TRUE;
return TRUE;
}
Bool
radeon_glamor_create_textured_pixmap(PixmapPtr pixmap)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
RADEONInfoPtr info = RADEONPTR(scrn);
struct radeon_pixmap *priv;
if ((info->use_glamor) == 0)
return TRUE;
priv = radeon_get_pixmap_private(pixmap);
if (glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle,
priv->stride))
return TRUE;
else
return FALSE;
}
static PixmapPtr
radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
unsigned usage)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct radeon_pixmap *priv;
PixmapPtr pixmap, new_pixmap = NULL;
if (!(usage & RADEON_CREATE_PIXMAP_DRI2)) {
pixmap = glamor_create_pixmap(screen, w, h, depth, usage);
if (pixmap)
return pixmap;
}
if (w > 32767 || h > 32767)
return NullPixmap;
if (depth == 1)
return fbCreatePixmap(screen, w, h, depth, usage);
if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32)
return fbCreatePixmap(screen, w, h, depth, usage);
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
if (pixmap == NullPixmap)
return pixmap;
if (w && h) {
priv = calloc(1, sizeof (struct radeon_pixmap));
if (priv == NULL)
goto fallback_pixmap;
priv->bo = radeon_alloc_pixmap_bo(scrn, w, h, depth, usage,
pixmap->drawable.bitsPerPixel,
&priv->stride,
&priv->surface,
&priv->tiling_flags);
if (!priv->bo)
goto fallback_priv;
radeon_set_pixmap_private(pixmap, priv);
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, priv->stride, NULL);
if (!radeon_glamor_create_textured_pixmap(pixmap))
goto fallback_glamor;
}
return pixmap;
fallback_glamor:
if (usage & RADEON_CREATE_PIXMAP_DRI2) {
/* XXX need further work to handle the DRI2 failure case.
* Glamor don't know how to handle a BO only pixmap. Put
* a warning indicator here.
*/
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Failed to create textured DRI2 pixmap.");
return pixmap;
}
/* Create textured pixmap failed means glamor failed to
* create a texture from current BO for some reasons. We turn
* to create a new glamor pixmap and clean up current one.
* One thing need to be noted, this new pixmap doesn't
* has a priv and bo attached to it. It's glamor's responsbility
* to take care of it. Glamor will mark this new pixmap as a
* texture only pixmap and will never fallback to DDX layer
* afterwards.
*/
new_pixmap = glamor_create_pixmap(screen, w, h, depth, usage);
radeon_bo_unref(priv->bo);
fallback_priv:
free(priv);
fallback_pixmap:
fbDestroyPixmap(pixmap);
if (new_pixmap)
return new_pixmap;
else
return fbCreatePixmap(screen, w, h, depth, usage);
}
static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap)
{
if (pixmap->refcnt == 1) {
glamor_egl_destroy_textured_pixmap(pixmap);
radeon_set_pixmap_bo(pixmap, NULL);
}
fbDestroyPixmap(pixmap);
return TRUE;
}
Bool
radeon_glamor_init(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS | GLAMOR_USE_EGL_SCREEN |
GLAMOR_USE_SCREEN | GLAMOR_USE_PICTURE_SCREEN)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to initialize glamor.\n");
return FALSE;
}
if (!glamor_egl_init_textured_pixmap(screen)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to initialize textured pixmap of screen for glamor.\n");
return FALSE;
}
#if HAS_DIXREGISTERPRIVATEKEY
if (!dixRegisterPrivateKey(&glamor_pixmap_index, PRIVATE_PIXMAP, 0))
#else
if (!dixRequestPrivate(&glamor_pixmap_index, 0))
#endif
return FALSE;
screen->CreatePixmap = radeon_glamor_create_pixmap;
screen->DestroyPixmap = radeon_glamor_destroy_pixmap;
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Use GLAMOR acceleration.\n");
return TRUE;
}
void
radeon_glamor_flush(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
if (info->use_glamor)
glamor_block_handler(pScrn->pScreen);
}

93
src/radeon_glamor.h Normal file
View File

@@ -0,0 +1,93 @@
/*
* Copyright © 2011 Intel Corporation.
* 2012 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including
* the next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef RADEON_GLAMOR_H
#define RADEON_GLAMOR_H
#ifdef USE_GLAMOR
#include "radeon_surface.h"
Bool radeon_glamor_pre_init(ScrnInfoPtr scrn);
Bool radeon_glamor_init(ScreenPtr screen);
Bool radeon_glamor_create_screen_resources(ScreenPtr screen);
void radeon_glamor_free_screen(int scrnIndex, int flags);
void radeon_glamor_flush(ScrnInfoPtr pScrn);
Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap);
void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst);
Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap);
struct radeon_pixmap {
struct radeon_surface surface;
struct radeon_bo *bo;
uint32_t tiling_flags;
int stride;
};
#if HAS_DEVPRIVATEKEYREC
extern DevPrivateKeyRec glamor_pixmap_index;
#else
extern int glamor_pixmap_index;
#endif
static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
{
#if HAS_DEVPRIVATEKEYREC
return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
#else
return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
#endif
}
static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
{
dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
}
#else
static inline Bool radeon_glamor_pre_init(ScrnInfoPtr scrn) { return FALSE; }
static inline Bool radeon_glamor_init(ScreenPtr screen) { return FALSE; }
static inline Bool radeon_glamor_create_screen_resources(ScreenPtr screen) { return FALSE; }
static inline void radeon_glamor_free_screen(int scrnIndex, int flags) { }
static inline void radeon_glamor_flush(ScrnInfoPtr pScrn) { }
static inline Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap) { return FALSE; }
static inline void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst) {}
static inline Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap) { return FALSE; }
static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap) { return NULL; }
#endif
#endif /* RADEON_GLAMOR_H */

View File

@@ -224,7 +224,7 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
return FALSE; return FALSE;
} }
if (info->dri2.enabled) { if (info->dri2.enabled || info->use_glamor) {
if (info->front_bo) { if (info->front_bo) {
PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
radeon_set_pixmap_bo(pPix, info->front_bo); radeon_set_pixmap_bo(pPix, info->front_bo);
@@ -234,6 +234,10 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
} }
} }
} }
if (info->use_glamor)
radeon_glamor_create_screen_resources(pScreen);
return TRUE; return TRUE;
} }
@@ -247,6 +251,9 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
(*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
pScreen->BlockHandler = RADEONBlockHandler_KMS; pScreen->BlockHandler = RADEONBlockHandler_KMS;
if (info->use_glamor)
radeon_glamor_flush(pScrn);
radeon_cs_flush_indirect(pScrn); radeon_cs_flush_indirect(pScrn);
} }
@@ -258,6 +265,7 @@ radeon_flush_callback(CallbackListPtr *list,
if (pScrn->vtSema) { if (pScrn->vtSema) {
radeon_cs_flush_indirect(pScrn); radeon_cs_flush_indirect(pScrn);
radeon_glamor_flush(pScrn);
} }
} }
@@ -416,6 +424,9 @@ static Bool RADEONPreInitAccel_KMS(ScrnInfoPtr pScrn)
return TRUE; return TRUE;
} }
if (radeon_glamor_pre_init(pScrn))
return TRUE;
if (info->ChipFamily == CHIP_FAMILY_PALM) { if (info->ChipFamily == CHIP_FAMILY_PALM) {
info->accel_state->allowHWDFS = RADEONIsFusionGARTWorking(pScrn); info->accel_state->allowHWDFS = RADEONIsFusionGARTWorking(pScrn);
} else } else
@@ -838,16 +849,18 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
} }
} }
info->exa_pixmaps = xf86ReturnOptValBool(info->Options, if (!info->use_glamor) {
OPTION_EXA_PIXMAPS, info->exa_pixmaps = xf86ReturnOptValBool(info->Options,
((info->vram_size > (32 * 1024 * 1024) && OPTION_EXA_PIXMAPS,
info->RenderAccel))); ((info->vram_size > (32 * 1024 * 1024) &&
if (info->exa_pixmaps) info->RenderAccel)));
xf86DrvMsg(pScrn->scrnIndex, X_INFO, if (info->exa_pixmaps)
"EXA: Driver will allow EXA pixmaps in VRAM\n"); xf86DrvMsg(pScrn->scrnIndex, X_INFO,
else "EXA: Driver will allow EXA pixmaps in VRAM\n");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, else
"EXA: Driver will not allow EXA pixmaps in VRAM\n"); xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"EXA: Driver will not allow EXA pixmaps in VRAM\n");
}
/* no tiled scanout on r6xx+ yet */ /* no tiled scanout on r6xx+ yet */
if (info->allowColorTiling) { if (info->allowColorTiling) {
@@ -1186,7 +1199,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
*/ */
/* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */ /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */
#endif #endif
if (info->r600_shadow_fb == FALSE) { if (!info->use_glamor && info->r600_shadow_fb == FALSE) {
/* Init Xv */ /* Init Xv */
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"Initializing Xv\n"); "Initializing Xv\n");
@@ -1322,7 +1335,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n"); xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n");
return FALSE; return FALSE;
} }
if (info->r600_shadow_fb == FALSE) { if (!info->use_glamor && info->r600_shadow_fb == FALSE) {
info->accel_state->exa = exaDriverAlloc(); info->accel_state->exa = exaDriverAlloc();
if (info->accel_state->exa == NULL) { if (info->accel_state->exa == NULL) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "exaDriverAlloc failed\n"); xf86DrvMsg(pScreen->myNum, X_ERROR, "exaDriverAlloc failed\n");