summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-08-05 17:26:28 -0400
committerAlex Deucher <alexdeucher@gmail.com>2010-08-05 17:36:36 -0400
commitb5bfdbd70d9671250957ccd41dfc8818850d257e (patch)
tree315fb46fde7773a628ad0b301a27278b48ff65a8
parenta3c59c6f6be7067421e348142da0ca13428dcd57 (diff)
r6xx/r7xx: add support for tiling with kms (v3)
Requires radeon drm 2.6.0 and updated mesa. v2: - fix lockup due to not emiting DB_DEPTH_INFO https://bugs.freedesktop.org/show_bug.cgi?id=28342 - fix drm minor version to deal with evergreen accel v3: rebase on current ddx git Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
-rw-r--r--src/drmmode_display.c7
-rw-r--r--src/r600_exa.c3
-rw-r--r--src/r600_state.h3
-rw-r--r--src/r6xx_accel.c18
-rw-r--r--src/radeon.h6
-rw-r--r--src/radeon_dri2.c10
-rw-r--r--src/radeon_exa.c26
-rw-r--r--src/radeon_kms.c103
8 files changed, 150 insertions, 26 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index e2d516b4..6a4a32d1 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1098,14 +1098,17 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
scrn->displayWidth = pitch;
info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
if (!info->front_bo)
goto fail;
- if (info->allowColorTiling)
- tiling_flags |= RADEON_TILING_MACRO;
+ /* no tiled scanout on r6xx+ yet */
+ if (info->allowColorTiling) {
+ if (info->ChipFamily < CHIP_FAMILY_R600)
+ tiling_flags |= RADEON_TILING_MACRO;
+ }
#if X_BYTE_ORDER == X_BIG_ENDIAN
switch (cpp) {
case 4:
tiling_flags |= RADEON_TILING_SWAP_32BIT;
break;
case 2:
diff --git a/src/r600_exa.c b/src/r600_exa.c
index 638bd382..911dba08 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -2148,12 +2148,15 @@ R600DrawInit(ScreenPtr pScreen)
info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap;
info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS;
info->accel_state->exa->FinishAccess = RADEONFinishAccess_CS;
info->accel_state->exa->UploadToScreen = R600UploadToScreenCS;
info->accel_state->exa->DownloadFromScreen = R600DownloadFromScreenCS;
+#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 5)
+ info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2;
+#endif
} else
#endif
#endif
{
info->accel_state->exa->PrepareAccess = R600PrepareAccess;
info->accel_state->exa->FinishAccess = R600FinishAccess;
diff --git a/src/r600_state.h b/src/r600_state.h
index 4e65bc1f..151f402a 100644
--- a/src/r600_state.h
+++ b/src/r600_state.h
@@ -327,12 +327,15 @@ R600SetAccelState(ScrnInfoPtr pScrn,
uint32_t vs_offset, uint32_t ps_offset,
int rop, Pixel planemask);
extern Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index);
extern void RADEONFinishAccess_CS(PixmapPtr pPix, int index);
extern void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align);
+extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
+ int depth, int usage_hint, int bitsPerPixel,
+ int *new_pitch);
extern void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv);
extern struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix);
extern Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix);
#endif
diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
index b34b6c5e..86817bdb 100644
--- a/src/r6xx_accel.c
+++ b/src/r6xx_accel.c
@@ -255,22 +255,27 @@ set_render_target(ScrnInfoPtr pScrn, drmBufPtr ib, cb_config_t *cb_conf, uint32_
RELOC_BATCH(cb_conf->bo, 0, domain);
END_BATCH();
BEGIN_BATCH(3 + 2);
EREG(ib, (CB_COLOR0_FRAG + (4 * cb_conf->id)), (0 >> 8)); // FMASK per-tile data base/256
RELOC_BATCH(cb_conf->bo, 0, domain);
END_BATCH();
- BEGIN_BATCH(12);
+ BEGIN_BATCH(9);
// pitch only for ARRAY_LINEAR_GENERAL, other tiling modes require addrlib
EREG(ib, (CB_COLOR0_SIZE + (4 * cb_conf->id)), ((pitch << PITCH_TILE_MAX_shift) |
(slice << SLICE_TILE_MAX_shift)));
EREG(ib, (CB_COLOR0_VIEW + (4 * cb_conf->id)), ((0 << SLICE_START_shift) |
(0 << SLICE_MAX_shift)));
- EREG(ib, (CB_COLOR0_INFO + (4 * cb_conf->id)), cb_color_info);
EREG(ib, (CB_COLOR0_MASK + (4 * cb_conf->id)), ((0 << CMASK_BLOCK_MAX_shift) |
(0 << FMASK_TILE_MAX_shift)));
END_BATCH();
+
+ BEGIN_BATCH(3 + 2);
+ EREG(ib, (CB_COLOR0_INFO + (4 * cb_conf->id)), cb_color_info);
+ RELOC_BATCH(cb_conf->bo, 0, domain);
+ END_BATCH();
+
}
static void
cp_set_surface_sync(ScrnInfoPtr pScrn, drmBufPtr ib, uint32_t sync_type, uint32_t size, uint64_t mc_addr,
struct radeon_bo *bo, uint32_t rdomains, uint32_t wdomain)
{
@@ -882,13 +887,19 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib)
sq_conf.num_es_stack_entries = 0;
break;
}
sq_setup(pScrn, ib, &sq_conf);
- BEGIN_BATCH(83);
+ /* set fake reloc for unused depth */
+ BEGIN_BATCH(3 + 2);
+ EREG(ib, DB_DEPTH_INFO, 0);
+ RELOC_BATCH(accel_state->shaders_bo, RADEON_GEM_DOMAIN_VRAM, 0);
+ END_BATCH();
+
+ BEGIN_BATCH(80);
if (info->ChipFamily < CHIP_FAMILY_RV770) {
EREG(ib, TA_CNTL_AUX, (( 3 << GRADIENT_CREDIT_shift) |
- (28 << TD_FIFO_CREDIT_shift)));
EREG(ib, VC_ENHANCE, 0);
EREG(ib, R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0);
EREG(ib, DB_DEBUG, 0x82000000); /* ? */
@@ -925,13 +936,12 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib)
E32(ib, 0); // SQ_PSTMP_RING_ITEMSIZE
E32(ib, 0); // SQ_FBUF_RING_ITEMSIZE
E32(ib, 0); // SQ_REDUC_RING_ITEMSIZE
E32(ib, 0); // SQ_GS_VERT_ITEMSIZE
// DB
- EREG(ib, DB_DEPTH_INFO, 0);
EREG(ib, DB_DEPTH_CONTROL, 0);
PACK0(ib, DB_RENDER_CONTROL, 2);
E32(ib, STENCIL_COMPRESS_DISABLE_bit | DEPTH_COMPRESS_DISABLE_bit);
if (info->ChipFamily < CHIP_FAMILY_RV770)
E32(ib, FORCE_SHADER_Z_ORDER_bit);
else
diff --git a/src/radeon.h b/src/radeon.h
index 55d673a3..d66cdd93 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -1032,12 +1032,18 @@ typedef struct {
struct radeon_cs *cs;
struct radeon_bo *cursor_bo[6];
uint64_t vram_size;
uint64_t gart_size;
drmmode_rec drmmode;
+ /* r6xx+ tile config */
+ uint32_t tile_config;
+ int group_bytes;
+ int num_channels;
+ int num_banks;
+ int r7xx_bank_op;
#else
/* fake bool */
Bool cs;
#endif
/* Xv bicubic filtering */
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index a0ed0857..9697bbc8 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -98,13 +98,16 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
pixmap->refcnt++;
} else {
/* tile the back buffer */
switch(attachments[i]) {
case DRI2BufferDepth:
case DRI2BufferDepthStencil:
- flags = RADEON_CREATE_PIXMAP_TILING_MACRO | RADEON_CREATE_PIXMAP_TILING_MICRO;
+ if (info->ChipFamily >= CHIP_FAMILY_R600)
+ flags = RADEON_CREATE_PIXMAP_TILING_MACRO;
+ else
+ 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;
@@ -180,13 +183,16 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
pixmap->refcnt++;
} else {
/* tile the back buffer */
switch(attachment) {
case DRI2BufferDepth:
case DRI2BufferDepthStencil:
- flags = RADEON_CREATE_PIXMAP_TILING_MACRO | RADEON_CREATE_PIXMAP_TILING_MICRO;
+ if (info->ChipFamily >= CHIP_FAMILY_R600)
+ flags = RADEON_CREATE_PIXMAP_TILING_MACRO;
+ else
+ 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;
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 7dd792e6..814c8641 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -427,17 +427,33 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
(tiling & RADEON_TILING_MACRO) &&
!RADEONMacroSwitch(width, height, bitsPerPixel, tiling,
info->ChipFamily >= CHIP_FAMILY_RV350)) {
tiling &= ~RADEON_TILING_MACRO;
}
- if (tiling) {
- height = RADEON_ALIGN(height, 16);
- pixmap_align = 256;
- } else
- pixmap_align = 64;
+ if (info->ChipFamily >= CHIP_FAMILY_R600) {
+ int bpe = bitsPerPixel / 8;
+
+ if (tiling & RADEON_TILING_MACRO) {
+ height = RADEON_ALIGN(height, info->num_banks * 8);
+ pixmap_align = MAX(info->num_banks,
+ (((info->group_bytes / 8) / bpe) * info->num_banks)) * 8 * bpe;
+ } else if (tiling & RADEON_TILING_MICRO) {
+ height = RADEON_ALIGN(height, 8);
+ pixmap_align = MAX(8, (info->group_bytes / (8 * bpe))) * bpe;
+ } else {
+ height = RADEON_ALIGN(height, 8);
+ pixmap_align = 256; /* 8 * bpe */
+ }
+ } else {
+ if (tiling) {
+ height = RADEON_ALIGN(height, 16);
+ pixmap_align = 256;
+ } else
+ pixmap_align = 64;
+ }
padded_width = ((width * bitsPerPixel + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
padded_width = RADEON_ALIGN(padded_width, pixmap_align);
size = height * padded_width;
new_priv = calloc(1, sizeof(struct radeon_exa_pixmap_priv));
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 772be8ff..ba13071f 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -418,12 +418,80 @@ static Bool radeon_open_drm_master(ScrnInfoPtr pScrn)
out:
info->drmmode.fd = info->dri2.drm_fd;
info->dri->drmFD = info->dri2.drm_fd;
return TRUE;
}
+static Bool r600_get_tile_config(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct drm_radeon_info ginfo;
+ int r;
+ uint32_t tmp;
+
+ if (info->ChipFamily < CHIP_FAMILY_R600)
+ return FALSE;
+
+#ifndef RADEON_INFO_TILING_CONFIG
+#define RADEON_INFO_TILING_CONFIG 0x6
+#endif
+
+ memset(&ginfo, 0, sizeof(ginfo));
+ ginfo.request = RADEON_INFO_TILING_CONFIG;
+ ginfo.value = (uintptr_t)&tmp;
+ r = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
+ if (r)
+ return FALSE;
+
+ info->tile_config = tmp;
+ info->r7xx_bank_op = 0;
+ if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
+ /* for now */
+ return FALSE;
+ } else {
+ switch((info->tile_config & 0xe) >> 1) {
+ case 0:
+ info->num_channels = 1;
+ break;
+ case 1:
+ info->num_channels = 2;
+ break;
+ case 2:
+ info->num_channels = 4;
+ break;
+ case 3:
+ info->num_channels = 8;
+ break;
+ default:
+ return FALSE;
+ }
+ switch((info->tile_config & 0x30) >> 4) {
+ case 0:
+ info->num_banks = 4;
+ break;
+ case 1:
+ info->num_banks = 8;
+ break;
+ default:
+ return FALSE;
+ }
+ switch((info->tile_config & 0xc0) >> 6) {
+ case 0:
+ info->group_bytes = 256;
+ break;
+ case 1:
+ info->group_bytes = 512;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
{
RADEONInfoPtr info;
RADEONEntPtr pRADEONEnt;
DevUnion* pPriv;
Gamma zeros = { 0.0, 0.0, 0.0 };
@@ -481,24 +549,12 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
if (!RADEONPreInitChipType_KMS(pScrn))
goto fail;
if (!radeon_alloc_dri(pScrn))
return FALSE;
- colorTilingDefault = info->ChipFamily >= CHIP_FAMILY_R300 &&
- info->ChipFamily <= CHIP_FAMILY_RS740;
-
- info->allowColorTiling = xf86ReturnOptValBool(info->Options,
- OPTION_COLOR_TILING, colorTilingDefault);
- if (info->ChipFamily >= CHIP_FAMILY_R600) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Color tiling is not yet supported on R600/R700\n");
- info->allowColorTiling = FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis");
-
if (radeon_open_drm_master(pScrn) == FALSE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
goto fail;
}
info->dri2.enabled = FALSE;
@@ -506,12 +562,31 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
if (info->dri->pKernelDRMVersion == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"RADEONDRIGetVersion failed to get the DRM version\n");
goto fail;
}
+ colorTilingDefault = info->ChipFamily >= CHIP_FAMILY_R300 &&
+ info->ChipFamily <= CHIP_FAMILY_RS740;
+
+ if (info->ChipFamily >= CHIP_FAMILY_R600) {
+ if (info->dri->pKernelDRMVersion->version_minor >= 6) {
+ info->allowColorTiling = xf86ReturnOptValBool(info->Options,
+ OPTION_COLOR_TILING, colorTilingDefault);
+ if (info->allowColorTiling)
+ info->allowColorTiling = r600_get_tile_config(pScrn);
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "R6xx+ KMS Color Tiling requires radeon drm 2.6.0 or newer\n");
+ } else
+ info->allowColorTiling = xf86ReturnOptValBool(info->Options,
+ OPTION_COLOR_TILING, colorTilingDefault);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis");
+
if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
goto fail;
}
if (info->drmmode.mode_res->count_crtcs == 1)
@@ -1035,14 +1110,16 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
0, RADEON_GEM_DOMAIN_VRAM, 0);
if (info->r600_shadow_fb == TRUE) {
if (radeon_bo_map(info->front_bo, 1)) {
ErrorF("Failed to map cursor buffer memory\n");
}
}
+ /* no tiled scanout on r6xx+ yet */
if (info->allowColorTiling) {
- tiling_flags |= RADEON_TILING_MACRO;
+ if (info->ChipFamily < CHIP_FAMILY_R600)
+ tiling_flags |= RADEON_TILING_MACRO;
}
#if X_BYTE_ORDER == X_BIG_ENDIAN
switch (cpp) {
case 4:
tiling_flags |= RADEON_TILING_SWAP_32BIT;
break;