Requires radeon drm 2.5.0 and updated mesa. Signed-off-by: Alex Deucher <alexdeucher@xxxxxxxxx> --- src/drmmode_display.c | 7 ++- src/r600_exa.c | 3 + src/r600_state.h | 3 + src/r6xx_accel.c | 12 ++++-- src/radeon.h | 6 +++ src/radeon_dri2.c | 10 ++++- src/radeon_exa.c | 26 ++++++++++-- src/radeon_kms.c | 99 ++++++++++++++++++++++++++++++++++++++++++------ 8 files changed, 140 insertions(+), 26 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 686de5e..c251110 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1099,8 +1099,11 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) 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: diff --git a/src/r600_exa.c b/src/r600_exa.c index 26b59d8..6b6c897 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -2305,6 +2305,9 @@ R600DrawInit(ScreenPtr pScreen) 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 diff --git a/src/r600_state.h b/src/r600_state.h index e9bfa10..c1e1ad3 100644 --- a/src/r600_state.h +++ b/src/r600_state.h @@ -339,6 +339,9 @@ R600SetAccelState(ScrnInfoPtr pScrn, 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); diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c index a835d71..cc82115 100644 --- a/src/r6xx_accel.c +++ b/src/r6xx_accel.c @@ -282,16 +282,21 @@ set_render_target(ScrnInfoPtr pScrn, drmBufPtr ib, cb_config_t *cb_conf, uint32_ 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(); + } void @@ -905,7 +910,7 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) sq_setup(pScrn, ib, &sq_conf); - BEGIN_BATCH(59); + BEGIN_BATCH(56); EREG(ib, SQ_VTX_BASE_VTX_LOC, 0); EREG(ib, SQ_VTX_START_INST_LOC, 0); @@ -921,7 +926,6 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) E32(ib, 0); // SQ_GS_VERT_ITEMSIZE // DB - EREG(ib, DB_DEPTH_INFO, 0); EREG(ib, DB_STENCIL_CLEAR, 0); EREG(ib, DB_DEPTH_CLEAR, 0); EREG(ib, DB_STENCILREFMASK, 0); diff --git a/src/radeon.h b/src/radeon.h index 56bc076..9ba3173 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -1036,6 +1036,12 @@ typedef struct { 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; diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 7d5205e..d10d9a8 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -101,7 +101,10 @@ radeon_dri2_create_buffers(DrawablePtr drawable, 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: @@ -183,7 +186,10 @@ radeon_dri2_create_buffer(DrawablePtr drawable, 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: diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 4f974c3..8dd69c4 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -461,11 +461,27 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, 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); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index e4c1c0b..1079e67 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -418,6 +418,70 @@ static Bool radeon_open_drm_master(ScrnInfoPtr pScrn) 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; + + memset(&ginfo, 0, sizeof(ginfo)); + ginfo.request = 0x5; + 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; @@ -481,18 +545,6 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) 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; @@ -506,6 +558,25 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) 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 >= 5) { + 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.5.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; @@ -1015,8 +1086,10 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) 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) { -- 1.5.6.3 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel