On Fri, Oct 2, 2015 at 5:11 AM, Michel Dänzer <mic...@daenzer.net> wrote: > From: Michel Dänzer <michel.daen...@amd.com> > > When using glamor acceleration, the pixmap's header has to have a height > that matches exactly what the actual height is minus the GPU memory > alignment. Otherwise CRTCs scanning out from the main scanout buffer > (e.g. every CRTC that isn't rotated or transformed in some way) won't > always work. This results in a bug where rotating one monitor in a > multi-monitor setup won't always work properly. Easiest way to reproduce > this: > > - Have two monitors (I've gotten this working with a 1920x1080 and > 1280x1024, along with two 1920x1080s) > - Rotate one of them from 0° to 90°, then rotate the same monitor from > 90° to 180°. The monitor that hasn't been rotated won't properly > update, and will stay on a blank screen > > This doesn't seem to make any difference when using EXA for > acceleration. > > Compared to Stephen Chandler's patch, this drops the height alignment > in most places and only keeps it where it's really necessary. > > Reported-by: Stephen Chandler Paul <cp...@redhat.com> > Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> Anyone want to port this to amdgpu? Alex > --- > > Stephen Chandler, > > thanks for the good catch, but I think we can take this even further. > Does this fix the problem for you as well? > > src/drmmode_display.c | 18 ++++++++---------- > 1 file changed, 8 insertions(+), 10 deletions(-) > > diff --git a/src/drmmode_display.c b/src/drmmode_display.c > index efc35f0..623124e 100644 > --- a/src/drmmode_display.c > +++ b/src/drmmode_display.c > @@ -525,6 +525,7 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, > RADEONInfoPtr info = RADEONPTR(pScrn); > drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; > drmmode_ptr drmmode = drmmode_crtc->drmmode; > + int aligned_height; > int size; > int ret; > unsigned long rotate_pitch; > @@ -547,9 +548,9 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, > rotate_pitch = > RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, > drmmode->cpp, 0)) > * drmmode->cpp; > - height = RADEON_ALIGN(height, drmmode_get_height_align(pScrn, 0)); > + aligned_height = RADEON_ALIGN(height, drmmode_get_height_align(pScrn, > 0)); > base_align = drmmode_get_base_align(pScrn, drmmode->cpp, 0); > - size = RADEON_ALIGN(rotate_pitch * height, RADEON_GPU_PAGE_SIZE); > + size = RADEON_ALIGN(rotate_pitch * aligned_height, > RADEON_GPU_PAGE_SIZE); > > scanout->bo = radeon_bo_open(drmmode->bufmgr, 0, size, base_align, > RADEON_GEM_DOMAIN_VRAM, 0); > @@ -633,7 +634,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr > mode, > drmModeModeInfo kmode; > int pitch; > uint32_t tiling_flags = 0; > - int height; > > if (info->allowColorTiling) { > if (info->ChipFamily >= CHIP_FAMILY_R600) > @@ -644,14 +644,13 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr > mode, > > pitch = RADEON_ALIGN(pScrn->displayWidth, > drmmode_get_pitch_align(pScrn, info->pixel_bytes, tiling_flags)) * > info->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, > - pScrn->virtualX, height, > + pScrn->virtualX, pScrn->virtualY, > pScrn->depth, pScrn->bitsPerPixel, > pitch, > info->front_bo->handle, > @@ -1789,6 +1788,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, > int height) > ScreenPtr screen = xf86ScrnToScreen(scrn); > uint32_t old_fb_id; > int i, pitch, old_width, old_height, old_pitch; > + int aligned_height; > uint32_t screen_size; > int cpp = info->pixel_bytes; > struct radeon_bo *front_bo; > @@ -1822,8 +1822,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, > int height) > } > > 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); > + aligned_height = RADEON_ALIGN(height, drmmode_get_height_align(scrn, > tiling_flags)); > + screen_size = RADEON_ALIGN(pitch * aligned_height, > RADEON_GPU_PAGE_SIZE); > base_align = 4096; > if (info->ChipFamily >= CHIP_FAMILY_R600) { > memset(&surface, 0, sizeof(struct radeon_surface)); > @@ -2473,7 +2473,6 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr > client, > unsigned int pitch; > int i; > uint32_t tiling_flags = 0; > - int height; > drmmode_flipdata_ptr flipdata; > drmmode_flipevtcarrier_ptr flipcarrier = NULL; > struct radeon_drm_queue_entry *drm_queue = NULL; > @@ -2487,7 +2486,6 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr > client, > > pitch = RADEON_ALIGN(scrn->displayWidth, > drmmode_get_pitch_align(scrn, info->pixel_bytes, tiling_flags)) * > info->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; > } > @@ -2503,7 +2501,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr > client, > * Create a new handle for the back buffer > */ > flipdata->old_fb_id = drmmode->fb_id; > - if (drmModeAddFB(drmmode->fd, scrn->virtualX, height, > + if (drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY, > scrn->depth, scrn->bitsPerPixel, pitch, > new_front_handle, &drmmode->fb_id)) > goto error; > -- > 2.6.0 > > _______________________________________________ > xorg-driver-ati mailing list > xorg-driver-...@lists.x.org > http://lists.x.org/mailman/listinfo/xorg-driver-ati _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel