summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2011-12-13 11:08:19 -0500
committerJerome Glisse <jglisse@redhat.com>2012-02-06 19:00:37 -0500
commit615033f2b5e3817e335e9d022fc9fdcf8ac8b11a (patch)
treece50a286a4e6b46beaa8c7f2e6ef0c667179aac7
parent36c190671081967bac6fff48aaf66d67b639a48c (diff)
r600-evergreen: use common surface allocator for tiling v11
Use libdrm common surface code so mesa,ddx have same idea about tiling surface and what their pitch should be and the alignment constraint. v2 fix remaining issue add new option to conditionaly enable v3 fix fbcon copy and r600 exa copy path v4 fix non tiled path 2D tiling on GPU >= R600, set it to false as default v5 adapt to pixel/element size split of libdrm/radeon v6 update to properly handle falling back to 1d tiled v6 final fix to tile split value on evergreen and newer v7 fix default array mode on r6xx, fix height alignment issue on evergreen v8 fix tile split value v9 add stencil tile split support, simplify dri2 for stencil with evergreen v10 Try to fix xv path regarding tiling. Adapt to libdrm API change. Try to fix case where there is no surface which means non tiled bo. v11 check for proper libdrm Signed-off-by: Jerome Glisse <jglisse@redhat.com>
-rw-r--r--configure.ac2
-rw-r--r--src/drmmode_display.c136
-rw-r--r--src/evergreen_accel.c157
-rw-r--r--src/evergreen_exa.c53
-rw-r--r--src/evergreen_state.h6
-rw-r--r--src/evergreen_textured_videofuncs.c7
-rw-r--r--src/r600_exa.c96
-rw-r--r--src/r600_state.h6
-rw-r--r--src/r600_textured_videofuncs.c7
-rw-r--r--src/r6xx_accel.c59
-rw-r--r--src/radeon.h14
-rw-r--r--src/radeon_dri2.c70
-rw-r--r--src/radeon_drm.h23
-rw-r--r--src/radeon_exa.c84
-rw-r--r--src/radeon_kms.c74
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;