diff options
-rw-r--r-- | src/radeon.h | 5 | ||||
-rw-r--r-- | src/radeon_dri2.c | 34 | ||||
-rw-r--r-- | src/radeon_drm.h | 23 | ||||
-rw-r--r-- | src/radeon_exa.c | 54 | ||||
-rw-r--r-- | src/radeon_exa_funcs.c | 3 | ||||
-rw-r--r-- | src/radeon_kms.c | 8 |
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); |