diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/drmmode_display.c | 136 | ||||
-rw-r--r-- | src/evergreen_accel.c | 157 | ||||
-rw-r--r-- | src/evergreen_exa.c | 53 | ||||
-rw-r--r-- | src/evergreen_state.h | 6 | ||||
-rw-r--r-- | src/evergreen_textured_videofuncs.c | 7 | ||||
-rw-r--r-- | src/r600_exa.c | 96 | ||||
-rw-r--r-- | src/r600_state.h | 6 | ||||
-rw-r--r-- | src/r600_textured_videofuncs.c | 7 | ||||
-rw-r--r-- | src/r6xx_accel.c | 59 | ||||
-rw-r--r-- | src/radeon.h | 14 | ||||
-rw-r--r-- | src/radeon_dri2.c | 70 | ||||
-rw-r--r-- | src/radeon_drm.h | 23 | ||||
-rw-r--r-- | src/radeon_exa.c | 84 | ||||
-rw-r--r-- | src/radeon_kms.c | 74 |
15 files changed, 671 insertions, 123 deletions
diff --git a/configure.ac b/configure.ac index ec544789..29f129ac 100644 --- a/configure.ac +++ b/configure.ac @@ -141,7 +141,7 @@ if test "$DRI" = yes; then AC_CHECK_HEADER(xf86drmMode.h,[DRM_MODE=yes],[DRM_MODE=no],[#include <stdint.h> #include <stdlib.h>]) if test "x$DRM_MODE" = xyes; then - PKG_CHECK_MODULES(LIBDRM_RADEON, [xorg-server >= 1.6.2 libdrm_radeon], + PKG_CHECK_MODULES(LIBDRM_RADEON, [xorg-server >= 1.6.2 libdrm >= 2.4.31 libdrm_radeon], [LIBDRM_RADEON=yes], [LIBDRM_RADEON=no]) if test "x$LIBDRM_RADEON" = xyes; then diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 02968d51..89ac6d7d 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -49,12 +49,16 @@ #include <X11/extensions/dpms.h> #endif -static PixmapPtr drmmode_create_bo_pixmap(ScreenPtr pScreen, +static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, int width, int height, int depth, int bpp, - int pitch, struct radeon_bo *bo) + int pitch, int tiling, + struct radeon_bo *bo) { + RADEONInfoPtr info = RADEONPTR(pScrn); + ScreenPtr pScreen = pScrn->pScreen; PixmapPtr pixmap; + struct radeon_surface *surface; pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0); if (!pixmap) @@ -67,6 +71,37 @@ static PixmapPtr drmmode_create_bo_pixmap(ScreenPtr pScreen, exaMoveInPixmap(pixmap); radeon_set_pixmap_bo(pixmap, bo); + surface = radeon_get_pixmap_surface(pixmap); + if (surface) { + memset(surface, 0, sizeof(struct radeon_surface)); + surface->npix_x = width; + surface->npix_y = height; + 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 = bpp / 8; + 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 & RADEON_TILING_MICRO) { + surface->flags = RADEON_SURF_CLR(surface->flags, MODE); + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); + } + if (tiling & 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; + } + } return pixmap; } @@ -159,7 +194,6 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); drmmode_crtc_private_ptr drmmode_crtc; - ScreenPtr pScreen = pScrn->pScreen; PixmapPtr pixmap; struct radeon_bo *bo; drmModeFBPtr fbcon; @@ -185,9 +219,9 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, return NULL; } - pixmap = drmmode_create_bo_pixmap(pScreen, fbcon->width, fbcon->height, + pixmap = drmmode_create_bo_pixmap(pScrn, fbcon->width, fbcon->height, fbcon->depth, fbcon->bpp, - fbcon->pitch, bo); + fbcon->pitch, 0, bo); if (!pixmap) return NULL; @@ -225,9 +259,13 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) return; 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; } @@ -235,10 +273,10 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) drmmode_get_pitch_align(pScrn, info->CurrentLayout.pixel_bytes, tiling_flags)) * info->CurrentLayout.pixel_bytes; - dst = drmmode_create_bo_pixmap(pScreen, pScrn->virtualX, + dst = drmmode_create_bo_pixmap(pScrn, pScrn->virtualX, pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel, pitch, - info->front_bo); + tiling_flags, info->front_bo); if (!dst) goto out_free_src; @@ -292,6 +330,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, pitch = RADEON_ALIGN(pScrn->displayWidth, drmmode_get_pitch_align(pScrn, info->CurrentLayout.pixel_bytes, tiling_flags)) * info->CurrentLayout.pixel_bytes; height = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)); + if (info->ChipFamily >= CHIP_FAMILY_R600) { + pitch = info->front_surface.level[0].pitch_bytes; + } if (drmmode->fb_id == 0) { ret = drmModeAddFB(drmmode->fd, @@ -503,12 +544,12 @@ drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) rotate_pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, drmmode->cpp, 0)) * drmmode->cpp; - rotate_pixmap = drmmode_create_bo_pixmap(pScrn->pScreen, + rotate_pixmap = drmmode_create_bo_pixmap(pScrn, width, height, pScrn->depth, pScrn->bitsPerPixel, rotate_pitch, - drmmode_crtc->rotate_bo); + 0, drmmode_crtc->rotate_bo); if (rotate_pixmap == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't allocate shadow pixmap for rotated CRTC\n"); @@ -1206,7 +1247,9 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) int screen_size; int cpp = info->CurrentLayout.pixel_bytes; struct radeon_bo *front_bo; - uint32_t tiling_flags = 0; + struct radeon_surface surface; + struct radeon_surface *psurface; + uint32_t tiling_flags = 0, base_align; PixmapPtr ppix = screen->GetScreenPixmap(screen); void *fb_shadow; @@ -1220,15 +1263,69 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) radeon_bo_wait(front_bo); 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(width, drmmode_get_pitch_align(scrn, cpp, tiling_flags)) * cpp; height = RADEON_ALIGN(height, drmmode_get_height_align(scrn, tiling_flags)); screen_size = RADEON_ALIGN(pitch * height, RADEON_GPU_PAGE_SIZE); + base_align = 4096; + if (info->ChipFamily >= CHIP_FAMILY_R600) { + memset(&surface, 0, sizeof(struct radeon_surface)); + surface.npix_x = width; + surface.npix_y = height; + 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; + } + screen_size = surface.bo_size; + base_align = surface.bo_alignment; + pitch = surface.level[0].pitch_bytes; + 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; + } xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocate new frame buffer %dx%d stride %d\n", @@ -1244,7 +1341,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) scrn->virtualY = height; scrn->displayWidth = pitch / cpp; - info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, 0, RADEON_GEM_DOMAIN_VRAM, 0); + info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, base_align, RADEON_GEM_DOMAIN_VRAM, 0); if (!info->front_bo) goto fail; @@ -1270,6 +1367,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) if (!info->r600_shadow_fb) { radeon_set_pixmap_bo(ppix, info->front_bo); + psurface = radeon_get_pixmap_surface(ppix); + *psurface = info->front_surface; screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, NULL); } else { @@ -1671,6 +1770,9 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *dat pitch = RADEON_ALIGN(scrn->displayWidth, drmmode_get_pitch_align(scrn, info->CurrentLayout.pixel_bytes, tiling_flags)) * info->CurrentLayout.pixel_bytes; height = RADEON_ALIGN(scrn->virtualY, drmmode_get_height_align(scrn, tiling_flags)); + if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) { + pitch = info->front_surface.level[0].pitch_bytes; + } /* * Create a new handle for the back buffer diff --git a/src/evergreen_accel.c b/src/evergreen_accel.c index 6610c288..3c76d38b 100644 --- a/src/evergreen_accel.c +++ b/src/evergreen_accel.c @@ -75,6 +75,57 @@ evergreen_start_3d(ScrnInfoPtr pScrn) } +unsigned eg_tile_split(unsigned tile_split) +{ + switch (tile_split) { + case 64: tile_split = 0; break; + case 128: tile_split = 1; break; + case 256: tile_split = 2; break; + case 512: tile_split = 3; break; + case 1024: tile_split = 4; break; + case 2048: tile_split = 5; break; + default: + case 4096: tile_split = 6; break; + } + return tile_split; +} + +static unsigned eg_macro_tile_aspect(unsigned macro_tile_aspect) +{ + switch (macro_tile_aspect) { + default: + case 1: macro_tile_aspect = 0; break; + case 2: macro_tile_aspect = 1; break; + case 4: macro_tile_aspect = 2; break; + case 8: macro_tile_aspect = 3; break; + } + return macro_tile_aspect; +} + +static unsigned eg_bank_wh(unsigned bankwh) +{ + switch (bankwh) { + default: + case 1: bankwh = 0; break; + case 2: bankwh = 1; break; + case 4: bankwh = 2; break; + case 8: bankwh = 3; break; + } + return bankwh; +} + +static unsigned eg_nbanks(unsigned nbanks) +{ + switch (nbanks) { + default: + case 2: nbanks = 0; break; + case 4: nbanks = 1; break; + case 8: nbanks = 2; break; + case 16: nbanks = 3; break; + } + return nbanks; +} + /* * Setup of functional groups */ @@ -154,12 +205,59 @@ void evergreen_set_render_target(ScrnInfoPtr pScrn, cb_config_t *cb_conf, uint32_t domain) { uint32_t cb_color_info, cb_color_attrib = 0, cb_color_dim; - int pitch, slice, h; + unsigned pitch, slice, w, h, array_mode, nbanks; + uint32_t tile_split, macro_aspect, bankw, bankh; RADEONInfoPtr info = RADEONPTR(pScrn); +#if defined(XF86DRM_MODE) + if (cb_conf->surface) { + switch (cb_conf->surface->level[0].mode) { + case RADEON_SURF_MODE_1D: + array_mode = 2; + break; + case RADEON_SURF_MODE_2D: + array_mode = 4; + break; + default: + array_mode = 0; + break; + } + w = cb_conf->surface->level[0].npix_x; + h = cb_conf->surface->level[0].npix_y; + pitch = (cb_conf->surface->level[0].nblk_x >> 3) - 1; + slice = ((cb_conf->surface->level[0].nblk_x * cb_conf->surface->level[0].nblk_y) / 64) - 1; + tile_split = cb_conf->surface->tile_split; + macro_aspect = cb_conf->surface->mtilea; + bankw = cb_conf->surface->bankw; + bankh = cb_conf->surface->bankh; + tile_split = eg_tile_split(tile_split); + macro_aspect = eg_macro_tile_aspect(macro_aspect); + bankw = eg_bank_wh(bankw); + bankh = eg_bank_wh(bankh); + } else +#endif + { + pitch = (cb_conf->w / 8) - 1; + h = RADEON_ALIGN(cb_conf->h, 8); + slice = ((cb_conf->w * h) / 64) - 1; + array_mode = cb_conf->array_mode; + w = cb_conf->w; + tile_split = 4; + macro_aspect = 0; + bankw = 0; + bankh = 0; + } + nbanks = info->num_banks; + nbanks = eg_nbanks(nbanks); + + cb_color_attrib |= (tile_split << CB_COLOR0_ATTRIB__TILE_SPLIT_shift)| + (nbanks << CB_COLOR0_ATTRIB__NUM_BANKS_shift) | + (bankw << CB_COLOR0_ATTRIB__BANK_WIDTH_shift) | + (bankh << CB_COLOR0_ATTRIB__BANK_HEIGHT_shift) | + (macro_aspect << CB_COLOR0_ATTRIB__MACRO_TILE_ASPECT_shift); cb_color_info = ((cb_conf->endian << ENDIAN_shift) | (cb_conf->format << CB_COLOR0_INFO__FORMAT_shift) | - (cb_conf->array_mode << CB_COLOR0_INFO__ARRAY_MODE_shift) | + (array_mode << CB_COLOR0_INFO__ARRAY_MODE_shift) | (cb_conf->number_type << NUMBER_TYPE_shift) | (cb_conf->comp_swap << COMP_SWAP_shift) | (cb_conf->source_format << SOURCE_FORMAT_shift) | @@ -185,10 +283,6 @@ evergreen_set_render_target(ScrnInfoPtr pScrn, cb_config_t *cb_conf, uint32_t do if (cb_conf->non_disp_tiling) cb_color_attrib |= CB_COLOR0_ATTRIB__NON_DISP_TILING_ORDER_bit; - pitch = (cb_conf->w / 8) - 1; - h = RADEON_ALIGN(cb_conf->h, 8); - slice = ((cb_conf->w * h) / 64) - 1; - switch (cb_conf->resource_type) { case BUFFER: /* number of elements in the surface */ @@ -196,7 +290,7 @@ evergreen_set_render_target(ScrnInfoPtr pScrn, cb_config_t *cb_conf, uint32_t do break; default: /* w/h of the surface */ - cb_color_dim = (((cb_conf->w - 1) << WIDTH_MAX_shift) | + cb_color_dim = (((w - 1) << WIDTH_MAX_shift) | ((cb_conf->h - 1) << HEIGHT_MAX_shift)); break; } @@ -601,17 +695,53 @@ evergreen_set_tex_resource(ScrnInfoPtr pScrn, tex_resource_t *tex_res, uint32_t RADEONInfoPtr info = RADEONPTR(pScrn); uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; uint32_t sq_tex_resource_word5, sq_tex_resource_word6, sq_tex_resource_word7; + uint32_t array_mode, pitch, tile_split, macro_aspect, bankw, bankh, nbanks; + +#if defined(XF86DRM_MODE) + if (tex_res->surface) { + switch (tex_res->surface->level[0].mode) { + case RADEON_SURF_MODE_1D: + array_mode = 2; + break; + case RADEON_SURF_MODE_2D: + array_mode = 4; + break; + default: + array_mode = 0; + break; + } + pitch = tex_res->surface->level[0].nblk_x >> 3; + tile_split = tex_res->surface->tile_split; + macro_aspect = tex_res->surface->mtilea; + bankw = tex_res->surface->bankw; + bankh = tex_res->surface->bankh; + tile_split = eg_tile_split(tile_split); + macro_aspect = eg_macro_tile_aspect(macro_aspect); + bankw = eg_bank_wh(bankw); + bankh = eg_bank_wh(bankh); + } else +#endif + { + array_mode = tex_res->array_mode; + pitch = (tex_res->pitch + 7) >> 3; + tile_split = 4; + macro_aspect = 0; + bankw = 0; + bankh = 0; + } + nbanks = info->num_banks; + nbanks = eg_nbanks(nbanks); sq_tex_resource_word0 = (tex_res->dim << DIM_shift); if (tex_res->w) - sq_tex_resource_word0 |= (((((tex_res->pitch + 7) >> 3) - 1) << PITCH_shift) | - ((tex_res->w - 1) << TEX_WIDTH_shift)); + sq_tex_resource_word0 |= ( ((pitch - 1) << PITCH_shift) | + ((tex_res->w - 1) << TEX_WIDTH_shift) ); if (tex_res->tile_type) sq_tex_resource_word0 |= SQ_TEX_RESOURCE_WORD0_0__NON_DISP_TILING_ORDER_bit; - sq_tex_resource_word1 = (tex_res->array_mode << SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_shift); + sq_tex_resource_word1 = (array_mode << SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_shift); if (tex_res->h) sq_tex_resource_word1 |= ((tex_res->h - 1) << TEX_HEIGHT_shift); @@ -640,12 +770,17 @@ evergreen_set_tex_resource(ScrnInfoPtr pScrn, tex_resource_t *tex_res, uint32_t (tex_res->last_array << LAST_ARRAY_shift)); sq_tex_resource_word6 = ((tex_res->min_lod << SQ_TEX_RESOURCE_WORD6_0__MIN_LOD_shift) | - (tex_res->perf_modulation << PERF_MODULATION_shift)); + (tex_res->perf_modulation << PERF_MODULATION_shift) | + (tile_split << SQ_TEX_RESOURCE_WORD6_0__TILE_SPLIT_shift)); if (tex_res->interlaced) sq_tex_resource_word6 |= INTERLACED_bit; sq_tex_resource_word7 = ((tex_res->format << SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift) | + (macro_aspect << SQ_TEX_RESOURCE_WORD7_0__MACRO_TILE_ASPECT_shift) | + (nbanks << SQ_TEX_RESOURCE_WORD7_0__NUM_BANKS_shift) | + (bankw << SQ_TEX_RESOURCE_WORD7_0__BANK_WIDTH_shift) | + (bankh << SQ_TEX_RESOURCE_WORD7_0__BANK_HEIGHT_shift) | (SQ_TEX_VTX_VALID_TEXTURE << SQ_TEX_RESOURCE_WORD7_0__TYPE_shift)); /* flush texture cache */ diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c index f17e5a69..8c32245c 100644 --- a/src/evergreen_exa.c +++ b/src/evergreen_exa.c @@ -77,6 +77,10 @@ EVERGREENPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) dst.offset = 0; dst.bo = radeon_get_pixmap_bo(pPix); dst.tiling_flags = radeon_get_pixmap_tiling(pPix); + dst.surface = radeon_get_pixmap_surface(pPix); + if (dst.surface->npix_x != pPix->drawable.width) { + dst.surface = NULL; + } dst.pitch = exaGetPixmapPitch(pPix) / (pPix->drawable.bitsPerPixel / 8); dst.width = pPix->drawable.width; @@ -129,6 +133,7 @@ EVERGREENPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) cb_conf.h = accel_state->dst_obj.height; cb_conf.base = accel_state->dst_obj.offset; cb_conf.bo = accel_state->dst_obj.bo; + cb_conf.surface = accel_state->dst_obj.surface; if (accel_state->dst_obj.bpp == 8) { cb_conf.format = COLOR_8; @@ -313,6 +318,7 @@ EVERGREENDoPrepareCopy(ScrnInfoPtr pScrn) tex_res.size = accel_state->src_size[0]; tex_res.bo = accel_state->src_obj[0].bo; tex_res.mip_bo = accel_state->src_obj[0].bo; + tex_res.surface = accel_state->src_obj[0].surface; if (accel_state->src_obj[0].bpp == 8) { tex_res.format = FMT_8; tex_res.dst_sel_x = SQ_SEL_1; /* R */ @@ -356,6 +362,7 @@ EVERGREENDoPrepareCopy(ScrnInfoPtr pScrn) cb_conf.h = accel_state->dst_obj.height; cb_conf.base = accel_state->dst_obj.offset; cb_conf.bo = accel_state->dst_obj.bo; + cb_conf.surface = accel_state->dst_obj.surface; if (accel_state->dst_obj.bpp == 8) { cb_conf.format = COLOR_8; cb_conf.comp_swap = 3; /* A */ @@ -467,8 +474,18 @@ EVERGREENPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, dst_obj.offset = 0; src_obj.bo = radeon_get_pixmap_bo(pSrc); dst_obj.bo = radeon_get_pixmap_bo(pDst); + dst_obj.surface = radeon_get_pixmap_surface(pDst); + src_obj.surface = radeon_get_pixmap_surface(pSrc); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); + if (dst_obj.surface->npix_x != pDst->drawable.width) { + dst_obj.surface = NULL; + dst_obj.tiling_flags = 0; + } + if (src_obj.surface->npix_x != pSrc->drawable.width) { + src_obj.surface = NULL; + src_obj.tiling_flags = 0; + } if (radeon_get_pixmap_bo(pSrc) == radeon_get_pixmap_bo(pDst)) accel_state->same_surface = TRUE; @@ -495,6 +512,9 @@ EVERGREENPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, drmmode_get_height_align(pScrn, accel_state->dst_obj.tiling_flags)); unsigned long size = height * accel_state->dst_obj.pitch * pDst->drawable.bitsPerPixel/8; + if (accel_state->dst_obj.surface) + size = accel_state->dst_obj.surface->bo_size; + if (accel_state->copy_area_bo) { radeon_bo_unref(accel_state->copy_area_bo); accel_state->copy_area_bo = NULL; @@ -576,6 +596,8 @@ EVERGREENCopy(PixmapPtr pDst, uint32_t orig_dst_tiling_flags = accel_state->dst_obj.tiling_flags; struct radeon_bo *orig_bo = accel_state->dst_obj.bo; int orig_rop = accel_state->rop; + struct radeon_surface *orig_dst_surface = accel_state->dst_obj.surface; + struct radeon_surface *orig_src_surface = accel_state->src_obj[0].surface; /* src to tmp */ accel_state->dst_obj.domain = RADEON_GEM_DOMAIN_VRAM; @@ -583,6 +605,7 @@ EVERGREENCopy(PixmapPtr pDst, accel_state->dst_obj.offset = 0; accel_state->dst_obj.tiling_flags = 0; accel_state->rop = 3; + accel_state->dst_obj.surface = NULL; EVERGREENDoPrepareCopy(pScrn); EVERGREENAppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h); EVERGREENDoCopy(pScrn); @@ -592,11 +615,13 @@ EVERGREENCopy(PixmapPtr pDst, accel_state->src_obj[0].bo = accel_state->copy_area_bo; accel_state->src_obj[0].offset = 0; accel_state->src_obj[0].tiling_flags = 0; + accel_state->src_obj[0].surface = NULL; accel_state->dst_obj.domain = orig_dst_domain; accel_state->dst_obj.bo = orig_bo; accel_state->dst_obj.offset = 0; accel_state->dst_obj.tiling_flags = orig_dst_tiling_flags; accel_state->rop = orig_rop; + accel_state->dst_obj.surface = orig_dst_surface; EVERGREENDoPrepareCopy(pScrn); EVERGREENAppendCopyVertex(pScrn, dstX, dstY, dstX, dstY, w, h); EVERGREENDoCopyVline(pDst); @@ -606,6 +631,7 @@ EVERGREENCopy(PixmapPtr pDst, accel_state->src_obj[0].bo = orig_bo; accel_state->src_obj[0].offset = 0; accel_state->src_obj[0].tiling_flags = orig_src_tiling_flags; + accel_state->src_obj[0].surface = orig_src_surface; } else EVERGREENAppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h); @@ -851,6 +877,7 @@ static Bool EVERGREENTextureSetup(PicturePtr pPict, PixmapPtr pPix, tex_res.format = EVERGREENTexFormats[i].card_fmt; tex_res.bo = accel_state->src_obj[unit].bo; tex_res.mip_bo = accel_state->src_obj[unit].bo; + tex_res.surface = accel_state->src_obj[unit].surface; #if X_BYTE_ORDER == X_BIG_ENDIAN switch (accel_state->src_obj[unit].bpp) { @@ -1133,8 +1160,18 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture, dst_obj.offset = 0; src_obj.bo = radeon_get_pixmap_bo(pSrc); dst_obj.bo = radeon_get_pixmap_bo(pDst); + dst_obj.surface = radeon_get_pixmap_surface(pDst); + src_obj.surface = radeon_get_pixmap_surface(pSrc); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); + if (dst_obj.surface->npix_x != pDst->drawable.width) { + dst_obj.surface = NULL; + dst_obj.tiling_flags = 0; + } + if (src_obj.surface->npix_x != pSrc->drawable.width) { + src_obj.surface = NULL; + src_obj.tiling_flags = 0; + } src_obj.pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8); dst_obj.pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8); @@ -1154,6 +1191,10 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture, mask_obj.bo = radeon_get_pixmap_bo(pMask); mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask); mask_obj.pitch = exaGetPixmapPitch(pMask) / (pMask->drawable.bitsPerPixel / 8); + mask_obj.surface = radeon_get_pixmap_surface(pMask); + if (mask_obj.surface->npix_x != pMask->drawable.width) { + mask_obj.surface = NULL; + } mask_obj.width = pMask->drawable.width; mask_obj.height = pMask->drawable.height; @@ -1262,6 +1303,7 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture, cb_conf.base = accel_state->dst_obj.offset; cb_conf.format = dst_format; cb_conf.bo = accel_state->dst_obj.bo; + cb_conf.surface = accel_state->dst_obj.surface; switch (pDstPicture->format) { case PICT_a8r8g8b8: @@ -1500,6 +1542,7 @@ EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, src_obj.domain = RADEON_GEM_DOMAIN_GTT; src_obj.bo = scratch; src_obj.tiling_flags = 0; + src_obj.surface = NULL; dst_obj.pitch = dst_pitch_hw; dst_obj.width = pDst->drawable.width; @@ -1509,6 +1552,11 @@ EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, dst_obj.domain = RADEON_GEM_DOMAIN_VRAM; dst_obj.bo = radeon_get_pixmap_bo(pDst); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); + dst_obj.surface = radeon_get_pixmap_surface(pDst); + if (dst_obj.surface->npix_x != pDst->drawable.width) { + dst_obj.surface = NULL; + dst_obj.tiling_flags = 0; + } if (!R600SetAccelState(pScrn, &src_obj, @@ -1639,6 +1687,10 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; src_obj.bo = radeon_get_pixmap_bo(pSrc); src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); + src_obj.surface = radeon_get_pixmap_surface(pSrc); + if (src_obj.surface->npix_x != pSrc->drawable.width) { + src_obj.surface = NULL; + } dst_obj.pitch = scratch_pitch; dst_obj.width = w; @@ -1648,6 +1700,7 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, dst_obj.bpp = bpp; dst_obj.domain = RADEON_GEM_DOMAIN_GTT; dst_obj.tiling_flags = 0; + dst_obj.surface = NULL; if (!R600SetAccelState(pScrn, &src_obj, diff --git a/src/evergreen_state.h b/src/evergreen_state.h index 5fd85f86..5a29f8fc 100644 --- a/src/evergreen_state.h +++ b/src/evergreen_state.h @@ -93,6 +93,9 @@ typedef struct { int blend_enable; uint32_t blendcntl; struct radeon_bo *bo; +#ifdef XF86DRM_MODE + struct radeon_surface *surface; +#endif } cb_config_t; /* Shader */ @@ -179,6 +182,9 @@ typedef struct { int min_lod; struct radeon_bo *bo; struct radeon_bo *mip_bo; +#ifdef XF86DRM_MODE + struct radeon_surface *surface; +#endif } tex_resource_t; /* Texture sampler */ diff --git a/src/evergreen_textured_videofuncs.c b/src/evergreen_textured_videofuncs.c index d27a02ac..4cf86403 100644 --- a/src/evergreen_textured_videofuncs.c +++ b/src/evergreen_textured_videofuncs.c @@ -158,6 +158,10 @@ EVERGREENDisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) src_obj.offset = 0; dst_obj.bo = radeon_get_pixmap_bo(pPixmap); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pPixmap); + dst_obj.surface = radeon_get_pixmap_surface(pPixmap); + if (dst_obj.surface->npix_x != pPixmap->drawable.width) { + dst_obj.surface = NULL; + } dst_obj.pitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel / 8); @@ -248,6 +252,7 @@ EVERGREENDisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) tex_res.size = accel_state->src_size[0]; tex_res.bo = accel_state->src_obj[0].bo; tex_res.mip_bo = accel_state->src_obj[0].bo; + tex_res.surface = NULL; tex_res.format = FMT_8; tex_res.dst_sel_x = SQ_SEL_X; /* Y */ @@ -340,6 +345,7 @@ EVERGREENDisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) tex_res.size = accel_state->src_size[0]; tex_res.bo = accel_state->src_obj[0].bo; tex_res.mip_bo = accel_state->src_obj[0].bo; + tex_res.surface = NULL; tex_res.format = FMT_8_8; if (pPriv->id == FOURCC_UYVY) @@ -406,6 +412,7 @@ EVERGREENDisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) cb_conf.h = accel_state->dst_obj.height; cb_conf.base = accel_state->dst_obj.offset; cb_conf.bo = accel_state->dst_obj.bo; + cb_conf.surface = accel_state->dst_obj.surface; switch (accel_state->dst_obj.bpp) { case 16: diff --git a/src/r600_exa.c b/src/r600_exa.c index b0c66ee4..47218d81 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -62,15 +62,14 @@ R600SetAccelState(ScrnInfoPtr pScrn, memcpy(&accel_state->src_obj[0], src0, sizeof(struct r600_accel_object)); accel_state->src_size[0] = src0->pitch * src0->height * (src0->bpp/8); #if defined(XF86DRM_MODE) - if (info->cs) { - pitch_align = drmmode_get_pitch_align(pScrn, - accel_state->src_obj[0].bpp / 8, - accel_state->src_obj[0].tiling_flags) - 1; - base_align = drmmode_get_base_align(pScrn, - accel_state->src_obj[0].bpp / 8, - accel_state->src_obj[0].tiling_flags) - 1; - } + if (info->cs && src0->surface) { + accel_state->src_size[0] = src0->surface->bo_size; + } else #endif + { + accel_state->src_obj[0].surface = NULL; + } + /* bad pitch */ if (accel_state->src_obj[0].pitch & pitch_align) RADEON_FALLBACK(("Bad src pitch 0x%08x\n", accel_state->src_obj[0].pitch)); @@ -88,15 +87,14 @@ R600SetAccelState(ScrnInfoPtr pScrn, memcpy(&accel_state->src_obj[1], src1, sizeof(struct r600_accel_object)); accel_state->src_size[1] = src1->pitch * src1->height * (src1->bpp/8); #if defined(XF86DRM_MODE) - if (info->cs) { - pitch_align = drmmode_get_pitch_align(pScrn, - accel_state->src_obj[1].bpp / 8, - accel_state->src_obj[1].tiling_flags) - 1; - base_align = drmmode_get_base_align(pScrn, - accel_state->src_obj[1].bpp / 8, - accel_state->src_obj[1].tiling_flags) - 1; - } + if (info->cs && src1->surface) { + accel_state->src_size[1] = src1->surface->bo_size; + } else #endif + { + accel_state->src_obj[1].surface = NULL; + } + /* bad pitch */ if (accel_state->src_obj[1].pitch & pitch_align) RADEON_FALLBACK(("Bad src pitch 0x%08x\n", accel_state->src_obj[1].pitch)); @@ -113,15 +111,14 @@ R600SetAccelState(ScrnInfoPtr pScrn, memcpy(&accel_state->dst_obj, dst, sizeof(struct r600_accel_object)); accel_state->dst_size = dst->pitch * dst->height * (dst->bpp/8); #if defined(XF86DRM_MODE) - if (info->cs) { - pitch_align = drmmode_get_pitch_align(pScrn, - accel_state->dst_obj.bpp / 8, - accel_state->dst_obj.tiling_flags) - 1; - base_align = drmmode_get_base_align(pScrn, - accel_state->dst_obj.bpp / 8, - accel_state->dst_obj.tiling_flags) - 1; - } + if (info->cs && dst->surface) { + accel_state->dst_size = dst->surface->bo_size; + } else #endif + { + accel_state->dst_obj.surface = NULL; + accel_state->dst_obj.tiling_flags = 0; + } if (accel_state->dst_obj.pitch & pitch_align) RADEON_FALLBACK(("Bad dst pitch 0x%08x\n", accel_state->dst_obj.pitch)); @@ -197,6 +194,10 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) dst.offset = 0; dst.bo = radeon_get_pixmap_bo(pPix); dst.tiling_flags = radeon_get_pixmap_tiling(pPix); + dst.surface = radeon_get_pixmap_surface(pPix); + if (dst.surface->npix_x != pPix->drawable.width) { + dst.surface = NULL; + } } else #endif { @@ -254,6 +255,7 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) cb_conf.h = accel_state->dst_obj.height; cb_conf.base = accel_state->dst_obj.offset; cb_conf.bo = accel_state->dst_obj.bo; + cb_conf.surface = accel_state->dst_obj.surface; if (accel_state->dst_obj.bpp == 8) { cb_conf.format = COLOR_8; @@ -433,6 +435,7 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn) tex_res.size = accel_state->src_size[0]; tex_res.bo = accel_state->src_obj[0].bo; tex_res.mip_bo = accel_state->src_obj[0].bo; + tex_res.surface = accel_state->src_obj[0].surface; if (accel_state->src_obj[0].bpp == 8) { tex_res.format = FMT_8; tex_res.dst_sel_x = SQ_SEL_1; /* R */ @@ -477,6 +480,7 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn) cb_conf.h = accel_state->dst_obj.height; cb_conf.base = accel_state->dst_obj.offset; cb_conf.bo = accel_state->dst_obj.bo; + cb_conf.surface = accel_state->dst_obj.surface; if (accel_state->dst_obj.bpp == 8) { cb_conf.format = COLOR_8; cb_conf.comp_swap = 3; /* A */ @@ -591,6 +595,16 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, dst_obj.bo = radeon_get_pixmap_bo(pDst); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); + src_obj.surface = radeon_get_pixmap_surface(pSrc); + dst_obj.surface = radeon_get_pixmap_surface(pDst); + if (dst_obj.surface->npix_x != pDst->drawable.width) { + dst_obj.surface = NULL; + dst_obj.tiling_flags = 0; + } + if (src_obj.surface->npix_x != pSrc->drawable.width) { + src_obj.surface = NULL; + src_obj.tiling_flags = 0; + } if (radeon_get_pixmap_bo(pSrc) == radeon_get_pixmap_bo(pDst)) accel_state->same_surface = TRUE; } else @@ -626,10 +640,13 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, #if defined(XF86DRM_MODE) unsigned height = RADEON_ALIGN(pDst->drawable.height, drmmode_get_height_align(pScrn, accel_state->dst_obj.tiling_flags)); + unsigned long size = accel_state->dst_obj.surface->bo_size; + unsigned long align = accel_state->dst_obj.surface->bo_alignment; #else unsigned height = pDst->drawable.height; -#endif unsigned long size = height * accel_state->dst_obj.pitch * pDst->drawable.bitsPerPixel/8; + unsigned long align = 0; +#endif #if defined(XF86DRM_MODE) if (info->cs) { @@ -637,7 +654,7 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, radeon_bo_unref(accel_state->copy_area_bo); accel_state->copy_area_bo = NULL; } - accel_state->copy_area_bo = radeon_bo_open(info->bufmgr, 0, size, 0, + accel_state->copy_area_bo = radeon_bo_open(info->bufmgr, 0, size, align, RADEON_GEM_DOMAIN_VRAM, 0); if (accel_state->copy_area_bo == NULL) @@ -979,6 +996,7 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix, tex_res.format = R600TexFormats[i].card_fmt; tex_res.bo = accel_state->src_obj[unit].bo; tex_res.mip_bo = accel_state->src_obj[unit].bo; + tex_res.surface = accel_state->src_obj[unit].surface; tex_res.request_size = 1; #if X_BYTE_ORDER == X_BIG_ENDIAN @@ -1294,6 +1312,16 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, dst_obj.bo = radeon_get_pixmap_bo(pDst); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); + dst_obj.surface = radeon_get_pixmap_surface(pDst); + src_obj.surface = radeon_get_pixmap_surface(pSrc); + if (dst_obj.surface->npix_x != pDst->drawable.width) { + dst_obj.surface = NULL; + dst_obj.tiling_flags = 0; + } + if (src_obj.surface->npix_x != pSrc->drawable.width) { + src_obj.surface = NULL; + src_obj.tiling_flags = 0; + } } else #endif { @@ -1321,6 +1349,10 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, mask_obj.offset = 0; mask_obj.bo = radeon_get_pixmap_bo(pMask); mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask); + mask_obj.surface = radeon_get_pixmap_surface(pMask); + if (mask_obj.surface->npix_x != pMask->drawable.width) { + mask_obj.surface = NULL; + } } else #endif { @@ -1432,6 +1464,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, cb_conf.base = accel_state->dst_obj.offset; cb_conf.format = dst_format; cb_conf.bo = accel_state->dst_obj.bo; + cb_conf.surface = accel_state->dst_obj.surface; switch (pDstPicture->format) { case PICT_a8r8g8b8: @@ -1868,6 +1901,7 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, src_obj.domain = RADEON_GEM_DOMAIN_GTT; src_obj.bo = scratch; src_obj.tiling_flags = 0; + src_obj.surface = NULL; dst_obj.pitch = dst_pitch_hw; dst_obj.width = pDst->drawable.width; @@ -1877,6 +1911,11 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, dst_obj.domain = RADEON_GEM_DOMAIN_VRAM; dst_obj.bo = radeon_get_pixmap_bo(pDst); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); + dst_obj.surface = radeon_get_pixmap_surface(pDst); + if (dst_obj.surface->npix_x != pDst->drawable.width) { + dst_obj.surface = NULL; + dst_obj.tiling_flags = 0; + } if (!R600SetAccelState(pScrn, &src_obj, @@ -2003,6 +2042,10 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; src_obj.bo = radeon_get_pixmap_bo(pSrc); src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); + src_obj.surface = radeon_get_pixmap_surface(pSrc); + if (src_obj.surface->npix_x != pSrc->drawable.width) { + src_obj.surface = NULL; + } dst_obj.pitch = scratch_pitch; dst_obj.width = w; @@ -2012,6 +2055,7 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, dst_obj.bpp = bpp; dst_obj.domain = RADEON_GEM_DOMAIN_GTT; dst_obj.tiling_flags = 0; + dst_obj.surface = NULL; if (!R600SetAccelState(pScrn, &src_obj, diff --git a/src/r600_state.h b/src/r600_state.h index d5785cdd..f6d5a880 100644 --- a/src/r600_state.h +++ b/src/r600_state.h @@ -56,6 +56,9 @@ typedef struct { int blend_enable; uint32_t blendcntl; struct radeon_bo *bo; +#ifdef XF86DRM_MODE + struct radeon_surface *surface; +#endif } cb_config_t; /* Depth buffer */ @@ -142,6 +145,9 @@ typedef struct { int interlaced; struct radeon_bo *bo; struct radeon_bo *mip_bo; +#ifdef XF86DRM_MODE + struct radeon_surface *surface; +#endif } tex_resource_t; /* Texture sampler */ diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c index aab43f3a..fbaa9b15 100644 --- a/src/r600_textured_videofuncs.c +++ b/src/r600_textured_videofuncs.c @@ -170,6 +170,10 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) src_obj.offset = 0; dst_obj.bo = radeon_get_pixmap_bo(pPixmap); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pPixmap); + dst_obj.surface = radeon_get_pixmap_surface(pPixmap); + if (dst_obj.surface->npix_x != pPixmap->drawable.width) { + dst_obj.surface = NULL; + } } else #endif { @@ -186,6 +190,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; src_obj.bo = pPriv->src_bo[pPriv->currentBuffer]; src_obj.tiling_flags = 0; + src_obj.surface = NULL; dst_obj.width = pPixmap->drawable.width; dst_obj.height = pPixmap->drawable.height; @@ -270,6 +275,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) tex_res.size = accel_state->src_size[0]; tex_res.bo = accel_state->src_obj[0].bo; tex_res.mip_bo = accel_state->src_obj[0].bo; + tex_res.surface = NULL; tex_res.format = FMT_8; tex_res.dst_sel_x = SQ_SEL_X; /* Y */ @@ -431,6 +437,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) cb_conf.h = accel_state->dst_obj.height; cb_conf.base = accel_state->dst_obj.offset; cb_conf.bo = accel_state->dst_obj.bo; + cb_conf.surface = accel_state->dst_obj.surface; switch (accel_state->dst_obj.bpp) { case 16: diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c index d1a50858..8e6bffa7 100644 --- a/src/r6xx_accel.c +++ b/src/r6xx_accel.c @@ -223,12 +223,37 @@ void r600_set_render_target(ScrnInfoPtr pScrn, drmBufPtr ib, cb_config_t *cb_conf, uint32_t domain) { uint32_t cb_color_info, cb_color_control; - int pitch, slice, h; + unsigned pitch, slice, h, array_mode; RADEONInfoPtr info = RADEONPTR(pScrn); + +#if defined(XF86DRM_MODE) + if (cb_conf->surface) { + switch (cb_conf->surface->level[0].mode) { + case RADEON_SURF_MODE_1D: + array_mode = 2; + break; + case RADEON_SURF_MODE_2D: + array_mode = 4; + break; + default: + array_mode = 0; + break; + } + pitch = (cb_conf->surface->level[0].nblk_x >> 3) - 1; + slice = ((cb_conf->surface->level[0].nblk_x * cb_conf->surface->level[0].nblk_y) / 64) - 1; + } else +#endif + { + array_mode = cb_conf->array_mode; + pitch = (cb_conf->w / 8) - 1; + h = RADEON_ALIGN(cb_conf->h, 8); + slice = ((cb_conf->w * h) / 64) - 1; + } + cb_color_info = ((cb_conf->endian << ENDIAN_shift) | (cb_conf->format << CB_COLOR0_INFO__FORMAT_shift) | - (cb_conf->array_mode << CB_COLOR0_INFO__ARRAY_MODE_shift) | + (array_mode << CB_COLOR0_INFO__ARRAY_MODE_shift) | (cb_conf->number_type << NUMBER_TYPE_shift) | (cb_conf->comp_swap << COMP_SWAP_shift) | (cb_conf->tile_mode << CB_COLOR0_INFO__TILE_MODE_shift)); @@ -251,10 +276,6 @@ r600_set_render_target(ScrnInfoPtr pScrn, drmBufPtr ib, cb_config_t *cb_conf, ui if (cb_conf->source_format) cb_color_info |= SOURCE_FORMAT_bit; - pitch = (cb_conf->w / 8) - 1; - h = RADEON_ALIGN(cb_conf->h, 8); - slice = ((cb_conf->w * h) / 64) - 1; - BEGIN_BATCH(3 + 2); EREG(ib, (CB_COLOR0_BASE + (4 * cb_conf->id)), (cb_conf->base >> 8)); RELOC_BATCH(cb_conf->bo, 0, domain); @@ -602,12 +623,34 @@ r600_set_tex_resource(ScrnInfoPtr pScrn, drmBufPtr ib, tex_resource_t *tex_res, RADEONInfoPtr info = RADEONPTR(pScrn); uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; uint32_t sq_tex_resource_word5, sq_tex_resource_word6; + uint32_t array_mode, pitch; + +#if defined(XF86DRM_MODE) + if (tex_res->surface) { + switch (tex_res->surface->level[0].mode) { + case RADEON_SURF_MODE_1D: + array_mode = 2; + break; + case RADEON_SURF_MODE_2D: + array_mode = 4; + break; + default: + array_mode = 0; + break; + } + pitch = tex_res->surface->level[0].nblk_x >> 3; + } else +#endif + { + array_mode = tex_res->tile_mode; + pitch = (tex_res->pitch + 7) >> 3; + } sq_tex_resource_word0 = ((tex_res->dim << DIM_shift) | - (tex_res->tile_mode << SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift)); + (array_mode << SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift)); if (tex_res->w) - sq_tex_resource_word0 |= (((((tex_res->pitch + 7) >> 3) - 1) << PITCH_shift) | + sq_tex_resource_word0 |= (((pitch - 1) << PITCH_shift) | ((tex_res->w - 1) << TEX_WIDTH_shift)); if (tex_res->tile_type) diff --git a/src/radeon.h b/src/radeon.h index d99fe3a2..ce9508c3 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -91,6 +91,7 @@ #include "radeon_cs.h" #include "radeon_dri2.h" #include "drmmode_display.h" +#include "radeon_surface.h" #else #include "radeon_dummy_bufmgr.h" #endif @@ -183,6 +184,7 @@ typedef enum { OPTION_PANEL_SIZE, OPTION_MIN_DOTCLOCK, OPTION_COLOR_TILING, + OPTION_COLOR_TILING_2D, #ifdef XvExtension OPTION_VIDEO_KEY, OPTION_RAGE_THEATRE_CRYSTAL, @@ -442,6 +444,9 @@ typedef struct _atomBiosHandle *atomBiosHandlePtr; struct radeon_exa_pixmap_priv { struct radeon_bo *bo; uint32_t tiling_flags; +#ifdef XF86DRM_MODE + struct radeon_surface surface; +#endif Bool bo_mapped; }; @@ -621,6 +626,9 @@ struct r600_accel_object { uint32_t domain; struct radeon_bo *bo; uint32_t tiling_flags; +#if defined(XF86DRM_MODE) + struct radeon_surface *surface; +#endif }; struct radeon_vbo_object { @@ -889,6 +897,7 @@ typedef struct { /* accel */ Bool RenderAccel; /* Render */ Bool allowColorTiling; + Bool allowColorTiling2D; Bool tilingEnabled; /* mirror of sarea->tiling_enabled */ struct radeon_accel_state *accel_state; Bool accelOn; @@ -1014,6 +1023,8 @@ typedef struct { int num_channels; int num_banks; int r7xx_bank_op; + struct radeon_surface_manager *surf_man; + struct radeon_surface front_surface; #else /* fake bool */ Bool cs; @@ -1231,6 +1242,7 @@ extern void RADEONPMFini(ScrnInfoPtr pScrn); #ifdef USE_EXA /* radeon_exa.c */ +extern unsigned eg_tile_split(unsigned tile_split); extern Bool RADEONSetupMemEXA(ScreenPtr pScreen); extern Bool radeon_transform_is_affine_or_scaled(PictTransformPtr t); @@ -1322,6 +1334,7 @@ extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn, int num, const char *file, const char *func, int line); void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size); +struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix); #endif struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix); void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo); @@ -1670,6 +1683,7 @@ enum { RADEON_CREATE_PIXMAP_TILING_MACRO = 0x10000000, RADEON_CREATE_PIXMAP_TILING_MICRO = 0x20000000, RADEON_CREATE_PIXMAP_DEPTH = 0x40000000, /* for r200 */ + RADEON_CREATE_PIXMAP_SZBUFFER = 0x80000000, /* for eg */ }; #endif /* _RADEON_H_ */ diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 5a7ebd41..835575f7 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -244,10 +244,10 @@ radeon_dri2_create_buffer(DrawablePtr drawable, struct dri2_buffer_priv *privates; PixmapPtr pixmap, depth_pixmap; struct radeon_exa_pixmap_priv *driver_priv; - int need_enlarge = 0; int flags; unsigned front_width; uint32_t tiling = 0; + unsigned aligned_width = drawable->width; pixmap = pScreen->GetScreenPixmap(pScreen); front_width = pixmap->drawable.width; @@ -271,9 +271,15 @@ radeon_dri2_create_buffer(DrawablePtr drawable, /* macro is the preferred setting, but the 2D detiling for software * fallbacks in mesa still has issues on some configurations */ - if (info->ChipFamily >= CHIP_FAMILY_R600) - flags = RADEON_CREATE_PIXMAP_TILING_MICRO; - else + if (info->ChipFamily >= CHIP_FAMILY_R600) { + if (info->allowColorTiling2D) { + flags = RADEON_CREATE_PIXMAP_TILING_MACRO; + } else { + flags = RADEON_CREATE_PIXMAP_TILING_MICRO; + } + if (info->ChipFamily >= CHIP_FAMILY_CEDAR) + flags |= RADEON_CREATE_PIXMAP_SZBUFFER; + } else flags = RADEON_CREATE_PIXMAP_TILING_MACRO | RADEON_CREATE_PIXMAP_TILING_MICRO; if (IS_R200_3D || info->ChipFamily == CHIP_FAMILY_RV200 || info->ChipFamily == CHIP_FAMILY_RADEON) flags |= RADEON_CREATE_PIXMAP_DEPTH; @@ -283,24 +289,30 @@ radeon_dri2_create_buffer(DrawablePtr drawable, * fallbacks in mesa still has issues on some configurations */ if (info->ChipFamily >= CHIP_FAMILY_R600) { - flags = RADEON_CREATE_PIXMAP_TILING_MICRO; + if (info->allowColorTiling2D) { + flags = RADEON_CREATE_PIXMAP_TILING_MACRO; + } else { + flags = RADEON_CREATE_PIXMAP_TILING_MICRO; + } if (info->ChipFamily >= CHIP_FAMILY_CEDAR) - need_enlarge = 1; + flags |= RADEON_CREATE_PIXMAP_SZBUFFER; } else flags = RADEON_CREATE_PIXMAP_TILING_MACRO | RADEON_CREATE_PIXMAP_TILING_MICRO; if (IS_R200_3D || info->ChipFamily == CHIP_FAMILY_RV200 || info->ChipFamily == CHIP_FAMILY_RADEON) flags |= RADEON_CREATE_PIXMAP_DEPTH; + break; case DRI2BufferBackLeft: case DRI2BufferBackRight: case DRI2BufferFakeFrontLeft: case DRI2BufferFakeFrontRight: - if (info->ChipFamily >= CHIP_FAMILY_R600) - /* macro is the preferred setting, but the 2D detiling for software - * fallbacks in mesa still has issues on some configurations - */ - flags = RADEON_CREATE_PIXMAP_TILING_MICRO; - else + if (info->ChipFamily >= CHIP_FAMILY_R600) { + if (info->allowColorTiling2D) { + flags = RADEON_CREATE_PIXMAP_TILING_MACRO; + } else { + flags = RADEON_CREATE_PIXMAP_TILING_MICRO; + } + } else flags = RADEON_CREATE_PIXMAP_TILING_MACRO; break; default: @@ -312,39 +324,6 @@ radeon_dri2_create_buffer(DrawablePtr drawable, if (flags & RADEON_CREATE_PIXMAP_TILING_MACRO) tiling |= RADEON_TILING_MACRO; - if (need_enlarge) { - /* evergreen uses separate allocations for depth and stencil - * so we make an extra large depth buffer to cover stencil - * as well. - */ - int depth = (format != 0) ? format : drawable->depth; - unsigned aligned_width = drawable->width; - unsigned width_align = drmmode_get_pitch_align(pScrn, drawable->depth / 8, tiling); - unsigned aligned_height; - unsigned height_align = drmmode_get_height_align(pScrn, tiling); - unsigned base_align = drmmode_get_base_align(pScrn, drawable->depth / 8, tiling); - unsigned pitch_bytes; - unsigned size; - - if (aligned_width == front_width) - aligned_width = pScrn->virtualX; - aligned_width = RADEON_ALIGN(aligned_width, width_align); - pitch_bytes = aligned_width * (depth / 8); - aligned_height = RADEON_ALIGN(drawable->height, height_align); - size = pitch_bytes * aligned_height; - size = RADEON_ALIGN(size, base_align); - /* add additional size for stencil */ - size += aligned_width * aligned_height; - aligned_height = RADEON_ALIGN(size / pitch_bytes, height_align); - - pixmap = (*pScreen->CreatePixmap)(pScreen, - aligned_width, - aligned_height, - (format != 0)?format:drawable->depth, - flags); - - } else { - unsigned aligned_width = drawable->width; if (aligned_width == front_width) aligned_width = pScrn->virtualX; @@ -354,7 +333,6 @@ radeon_dri2_create_buffer(DrawablePtr drawable, drawable->height, (format != 0)?format:drawable->depth, flags); - } } if (!pixmap) diff --git a/src/radeon_drm.h b/src/radeon_drm.h index 49a5f81a..042e8222 100644 --- a/src/radeon_drm.h +++ b/src/radeon_drm.h @@ -800,12 +800,23 @@ struct drm_radeon_gem_create { uint32_t flags; }; -#define RADEON_TILING_MACRO 0x1 -#define RADEON_TILING_MICRO 0x2 -#define RADEON_TILING_SWAP_16BIT 0x4 -#define RADEON_TILING_SWAP_32BIT 0x8 -#define RADEON_TILING_SURFACE 0x10 /* this object requires a surface - * when mapped - i.e. front buffer */ +#define RADEON_TILING_MACRO 0x1 +#define RADEON_TILING_MICRO 0x2 +#define RADEON_TILING_SWAP_16BIT 0x4 +#define RADEON_TILING_SWAP_32BIT 0x8 +/* this object requires a surface when mapped - i.e. front buffer */ +#define RADEON_TILING_SURFACE 0x10 +#define RADEON_TILING_MICRO_SQUARE 0x20 +#define RADEON_TILING_EG_BANKW_SHIFT 8 +#define RADEON_TILING_EG_BANKW_MASK 0xf +#define RADEON_TILING_EG_BANKH_SHIFT 12 +#define RADEON_TILING_EG_BANKH_MASK 0xf +#define RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT 16 +#define RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK 0xf +#define RADEON_TILING_EG_TILE_SPLIT_SHIFT 24 +#define RADEON_TILING_EG_TILE_SPLIT_MASK 0xf +#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT 28 +#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK 0xf struct drm_radeon_gem_set_tiling { uint32_t handle; diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 554af363..99a58069 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -454,9 +454,12 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, RADEONInfoPtr info = RADEONPTR(pScrn); struct radeon_exa_pixmap_priv *new_priv; int pitch, base_align; - uint32_t size; + uint32_t size, heighta; uint32_t tiling = 0; int cpp = bitsPerPixel / 8; +#ifdef XF86DRM_MODE + struct radeon_surface surface; +#endif #ifdef EXA_MIXED_PIXMAPS if (info->accel_state->exa->flags & EXA_MIXED_PIXMAPS) { @@ -488,17 +491,78 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, tiling &= ~RADEON_TILING_MACRO; } - height = RADEON_ALIGN(height, drmmode_get_height_align(pScrn, tiling)); + heighta = RADEON_ALIGN(height, drmmode_get_height_align(pScrn, tiling)); pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, cpp, tiling)) * cpp; base_align = drmmode_get_base_align(pScrn, cpp, tiling); - size = RADEON_ALIGN(height * pitch, RADEON_GPU_PAGE_SIZE); + size = RADEON_ALIGN(heighta * pitch, RADEON_GPU_PAGE_SIZE); + memset(&surface, 0, sizeof(struct radeon_surface)); + +#ifdef XF86DRM_MODE + if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) { + if (width) { + surface.npix_x = width; + /* need to align height to 8 for old kernel */ + surface.npix_y = RADEON_ALIGN(height, 8); + 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 & RADEON_TILING_MICRO)) { + surface.flags = RADEON_SURF_CLR(surface.flags, MODE); + surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); + } + if ((tiling & RADEON_TILING_MACRO)) { + surface.flags = RADEON_SURF_CLR(surface.flags, MODE); + surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); + } + if (usage_hint & RADEON_CREATE_PIXMAP_SZBUFFER) { + surface.flags |= RADEON_SURF_ZBUFFER; + surface.flags |= RADEON_SURF_SBUFFER; + } + if (radeon_surface_best(info->surf_man, &surface)) { + return NULL; + } + if (radeon_surface_init(info->surf_man, &surface)) { + return NULL; + } + size = surface.bo_size; + base_align = surface.bo_alignment; + pitch = surface.level[0].pitch_bytes; + tiling = 0; + switch (surface.level[0].mode) { + case RADEON_SURF_MODE_2D: + tiling |= RADEON_TILING_MACRO; + tiling |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT; + tiling |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT; + tiling |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT; + tiling |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT; + tiling |= eg_tile_split(surface.stencil_tile_split) << RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT; + break; + case RADEON_SURF_MODE_1D: + tiling |= RADEON_TILING_MICRO; + break; + default: + break; + } + } + } +#endif new_priv = calloc(1, sizeof(struct radeon_exa_pixmap_priv)); - if (!new_priv) + if (!new_priv) { return NULL; + } - if (size == 0) + if (size == 0) { return new_priv; + } *new_pitch = pitch; @@ -513,6 +577,7 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, if (tiling && !radeon_bo_set_tiling(new_priv->bo, tiling, *new_pitch)) new_priv->tiling_flags = tiling; + new_priv->surface = surface; return new_priv; } @@ -535,6 +600,15 @@ struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix) return driver_priv->bo; } +#if defined(XF86DRM_MODE) +struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix) +{ + struct radeon_exa_pixmap_priv *driver_priv; + driver_priv = exaGetPixmapDriverPrivate(pPix); + return &driver_priv->surface; +} +#endif + uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix) { struct radeon_exa_pixmap_priv *driver_priv; 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; |