summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;