summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/radeon.h5
-rw-r--r--src/radeon_dri2.c34
-rw-r--r--src/radeon_drm.h23
-rw-r--r--src/radeon_exa.c54
-rw-r--r--src/radeon_exa_funcs.c3
-rw-r--r--src/radeon_kms.c8
6 files changed, 123 insertions, 4 deletions
diff --git a/src/radeon.h b/src/radeon.h
index 6b47a6a1..3a3631e2 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -1620,4 +1620,9 @@ static __inline__ int radeon_timedout(const struct timeval *endtime)
now.tv_usec > endtime->tv_usec : now.tv_sec > endtime->tv_sec;
}
+enum {
+ RADEON_CREATE_PIXMAP_TILING_MACRO = 0x10000000,
+ RADEON_CREATE_PIXMAP_TILING_MICRO = 0x20000000,
+};
+
#endif /* _RADEON_H_ */
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 9c862449..b52f9659 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -64,6 +64,7 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
PixmapPtr pixmap, depth_pixmap;
struct radeon_exa_pixmap_priv *driver_priv;
int i, r;
+ int flags = 0;
buffers = xcalloc(count, sizeof *buffers);
if (buffers == NULL) {
@@ -88,11 +89,22 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
pixmap = depth_pixmap;
pixmap->refcnt++;
} else {
- pixmap = (*pScreen->CreatePixmap)(pScreen,
+ /* tile the back buffer */
+ switch(attachments[i]) {
+ case DRI2BufferBackLeft:
+ case DRI2BufferBackRight:
+ case DRI2BufferFakeFrontLeft:
+ case DRI2BufferFakeFrontRight:
+ flags = RADEON_CREATE_PIXMAP_TILING_MACRO;
+ break;
+ default:
+ flags = 0;
+ }
+ pixmap = (*pScreen->CreatePixmap)(pScreen,
drawable->width,
drawable->height,
drawable->depth,
- 0);
+ flags);
}
if (attachments[i] == DRI2BufferDepth) {
@@ -126,6 +138,7 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
PixmapPtr pixmap, depth_pixmap;
struct radeon_exa_pixmap_priv *driver_priv;
int r;
+ int flags;
buffers = xcalloc(1, sizeof *buffers);
if (buffers == NULL) {
@@ -150,11 +163,26 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
pixmap = depth_pixmap;
pixmap->refcnt++;
} else {
+ /* tile the back buffer */
+ switch(attachment) {
+ case DRI2BufferDepth:
+ case DRI2BufferDepthStencil:
+ flags = RADEON_CREATE_PIXMAP_TILING_MACRO | RADEON_CREATE_PIXMAP_TILING_MICRO;
+ break;
+ case DRI2BufferBackLeft:
+ case DRI2BufferBackRight:
+ case DRI2BufferFakeFrontLeft:
+ case DRI2BufferFakeFrontRight:
+ flags = RADEON_CREATE_PIXMAP_TILING_MACRO;
+ break;
+ default:
+ flags = 0;
+ }
pixmap = (*pScreen->CreatePixmap)(pScreen,
drawable->width,
drawable->height,
(format != 0)?format:drawable->depth,
- 0);
+ flags);
}
if (attachment == DRI2BufferDepth) {
diff --git a/src/radeon_drm.h b/src/radeon_drm.h
index daa42d63..f974e193 100644
--- a/src/radeon_drm.h
+++ b/src/radeon_drm.h
@@ -503,6 +503,8 @@ typedef struct {
#define DRM_RADEON_GEM_WAIT_IDLE 0x24
#define DRM_RADEON_CS 0x26
#define DRM_RADEON_INFO 0x27
+#define DRM_RADEON_GEM_SET_TILING 0x28
+#define DRM_RADEON_GEM_GET_TILING 0x29
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
@@ -541,7 +543,8 @@ typedef struct {
#define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle)
#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
#define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info)
-
+#define DRM_IOCTL_RADEON_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling)
+#define DRM_IOCTL_RADEON_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling)
typedef struct drm_radeon_init {
enum {
@@ -797,6 +800,24 @@ struct drm_radeon_gem_create {
uint32_t flags;
};
+#define RADEON_TILING_MACRO 0x1
+#define RADEON_TILING_MICRO 0x2
+#define RADEON_TILING_SWAP 0x4
+#define RADEON_TILING_SURFACE 0x8 /* this object requires a surface
+ * when mapped - i.e. front buffer */
+
+struct drm_radeon_gem_set_tiling {
+ uint32_t handle;
+ uint32_t tiling_flags;
+ uint32_t pitch;
+};
+
+struct drm_radeon_gem_get_tiling {
+ uint32_t handle;
+ uint32_t tiling_flags;
+ uint32_t pitch;
+};
+
struct drm_radeon_gem_mmap {
uint32_t handle;
uint32_t pad;
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 25e3311b..ec65722c 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -403,6 +403,60 @@ void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align)
}
+void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
+ int depth, int usage_hint, int bitsPerPixel,
+ int *new_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_exa_pixmap_priv *new_priv;
+ int padded_width;
+ uint32_t size;
+ uint32_t tiling = 0;
+ int pixmap_align = 0;
+
+ if (usage_hint) {
+ if (info->allowColorTiling) {
+ if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MACRO)
+ tiling |= RADEON_TILING_MACRO;
+ if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MICRO)
+ tiling |= RADEON_TILING_MICRO;
+ }
+ }
+
+ if (tiling) {
+ height = (height + 15) & ~15;
+ pixmap_align = 255;
+ } else
+ pixmap_align = 63;
+
+ padded_width = ((width * bitsPerPixel + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
+ padded_width = (padded_width + pixmap_align) & ~pixmap_align;
+ size = height * padded_width;
+
+ new_priv = xcalloc(1, sizeof(struct radeon_exa_pixmap_priv));
+ if (!new_priv)
+ return NULL;
+
+ if (size == 0)
+ return new_priv;
+
+ *new_pitch = padded_width;
+
+ new_priv->bo = radeon_bo_open(info->bufmgr, 0, size,
+ 0, 0, 0);
+ if (!new_priv->bo) {
+ xfree(new_priv);
+ ErrorF("Failed to alloc memory\n");
+ return NULL;
+ }
+
+ if (tiling)
+ radeon_bo_set_tiling(new_priv->bo, tiling, *new_pitch);
+
+ return new_priv;
+}
+
static void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv)
{
struct radeon_exa_pixmap_priv *driver_priv = driverPriv;
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 605e5988..e48317f5 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -786,6 +786,9 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS;
info->accel_state->exa->FinishAccess = RADEONFinishAccess_CS;
+#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 5)
+ info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2;
+#endif
}
#endif
#endif
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index d93a40b2..0cabc53e 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -386,6 +386,11 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
if (info->IsSecondary)
zaphod_mask = 0x2;
+ info->allowColorTiling = xf86ReturnOptValBool(info->Options,
+ OPTION_COLOR_TILING, FALSE);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis");
+
bus_id = DRICreatePCIBusID(info->PciInfo);
if (drmmode_pre_init(pScrn, &info->drmmode, bus_id, "radeon", pScrn->bitsPerPixel / 8, zaphod_mask) == FALSE) {
xfree(bus_id);
@@ -860,6 +865,9 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
}
}
+ if (info->allowColorTiling) {
+ radeon_bo_set_tiling(info->front_bo, RADEON_TILING_MACRO, stride);
+ }
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->front_bo->size/1024);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Remaining VRAM size (used for pixmaps): %dK\n", remain_size_bytes/1024);