summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-08-19 19:01:30 +1000
committerDave Airlie <airlied@redhat.com>2009-08-19 19:03:03 +1000
commit72e0d1b2cb11a67b8e4be4c74913ee44dc051c5b (patch)
tree831ac42d8b00f26b96c5f714ce6c5fc86db1f4d1
parent479a6daefe46f985c415b0d000b1b1b820f3924e (diff)
radeon/kms: add initial colortiling support (disabled by default).
This requires an X server from git with createpixmap2 support fixed up in it. On 1.6 and previous it won't do any tiling, if you are running git server please upgrade to latest git. Option "AllowColorTiling" "true" to enable and do some testing
-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);