summaryrefslogtreecommitdiff
path: root/src/drmmode_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drmmode_display.c')
-rw-r--r--src/drmmode_display.c136
1 files changed, 119 insertions, 17 deletions
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