diff options
Diffstat (limited to 'src/radeon_kms.c')
-rw-r--r-- | src/radeon_kms.c | 74 |
1 files changed, 71 insertions, 3 deletions
diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 1604f25b..7ac4f05a 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -62,6 +62,7 @@ const OptionInfoRec RADEONOptions_KMS[] = { { OPTION_ACCEL_DFS, "AccelDFS", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_IGNORE_EDID, "IgnoreEDID", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_COLOR_TILING, "ColorTiling", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_COLOR_TILING_2D,"ColorTiling2D", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_RENDER_ACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE }, { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, @@ -158,6 +159,7 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); PixmapPtr pixmap; + struct radeon_surface *surface; pScreen->CreateScreenResources = info->CreateScreenResources; if (!(*pScreen->CreateScreenResources)(pScreen)) @@ -181,6 +183,10 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) if (info->front_bo) { PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); radeon_set_pixmap_bo(pPix, info->front_bo); + surface = radeon_get_pixmap_surface(pPix); + if (surface) { + *surface = info->front_surface; + } } } return TRUE; @@ -674,6 +680,8 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) if (!RADEONPreInitAccel_KMS(pScrn)) goto fail; + info->allowColorTiling2D = FALSE; + #ifdef EXA_MIXED_PIXMAPS /* don't enable tiling if accel is not enabled */ if (!info->r600_shadow_fb) { @@ -682,6 +690,11 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) info->ChipFamily >= CHIP_FAMILY_R300 && info->ChipFamily <= CHIP_FAMILY_CAYMAN; + /* 2D color tiling */ + if (info->ChipFamily >= CHIP_FAMILY_R600) { + info->allowColorTiling2D = xf86ReturnOptValBool(info->Options, OPTION_COLOR_TILING_2D, FALSE); + } + if (info->ChipFamily >= CHIP_FAMILY_R600) { /* set default group bytes, overridden by kernel info below */ info->group_bytes = 256; @@ -933,6 +946,7 @@ Bool RADEONScreenInit_KMS(int scrnIndex, ScreenPtr pScreen, front_ptr = info->FB; + info->surf_man = radeon_surface_manager_new(info->dri->drmFD); if (!info->bufmgr) info->bufmgr = radeon_bo_manager_gem_ctor(info->dri->drmFD); if (!info->bufmgr) { @@ -1209,6 +1223,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) int pitch, base_align; int total_size_bytes = 0; uint32_t tiling_flags = 0; + struct radeon_surface surface; if (info->accel_state->exa != NULL) { xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n"); @@ -1221,14 +1236,67 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) } if (info->allowColorTiling) { - if (info->ChipFamily >= CHIP_FAMILY_R600) - tiling_flags |= RADEON_TILING_MICRO; - else + if (info->ChipFamily >= CHIP_FAMILY_R600) { + if (info->allowColorTiling2D) { + tiling_flags |= RADEON_TILING_MACRO; + } else { + tiling_flags |= RADEON_TILING_MICRO; + } + } else tiling_flags |= RADEON_TILING_MACRO; } pitch = RADEON_ALIGN(pScrn->displayWidth, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp; screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * pitch; base_align = drmmode_get_base_align(pScrn, cpp, tiling_flags); + if (info->ChipFamily >= CHIP_FAMILY_R600) { + memset(&surface, 0, sizeof(struct radeon_surface)); + surface.npix_x = pScrn->displayWidth; + surface.npix_y = pScrn->virtualY; + surface.npix_z = 1; + surface.blk_w = 1; + surface.blk_h = 1; + surface.blk_d = 1; + surface.array_size = 1; + surface.last_level = 0; + surface.bpe = cpp; + surface.nsamples = 1; + surface.flags = RADEON_SURF_SCANOUT; + surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); + surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE); + if (tiling_flags & RADEON_TILING_MICRO) { + surface.flags = RADEON_SURF_CLR(surface.flags, MODE); + surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); + } + if (tiling_flags & RADEON_TILING_MACRO) { + surface.flags = RADEON_SURF_CLR(surface.flags, MODE); + surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); + } + if (radeon_surface_best(info->surf_man, &surface)) { + return FALSE; + } + if (radeon_surface_init(info->surf_man, &surface)) { + return FALSE; + } + pitch = surface.level[0].pitch_bytes; + screen_size = surface.bo_size; + base_align = surface.bo_alignment; + tiling_flags = 0; + switch (surface.level[0].mode) { + case RADEON_SURF_MODE_2D: + tiling_flags |= RADEON_TILING_MACRO; + tiling_flags |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT; + tiling_flags |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT; + tiling_flags |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT; + tiling_flags |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT; + break; + case RADEON_SURF_MODE_1D: + tiling_flags |= RADEON_TILING_MICRO; + break; + default: + break; + } + info->front_surface = surface; + } { int cursor_size = 64 * 4 * 64; int c; |