Wrong virtualX when using vesa driver with no shadowFB

Stefano Panella stefano.panella at citrix.com
Fri Feb 14 03:47:43 PST 2014


Hi all,

I have a question regarding the vesa driver stride when using horizontal 
resolution not multiple which do not play nicely with HW constrains for 
the stride.

I am working in a Xen/qemu environment where we emulate a Bochs VBE.

Our linux guests will usually use the vesa Xorg driver.

The problem I have noticed happen when we do not use the shadowFB and we 
have a mode like 1366x768 with stride of 5504 which needs to be 64 bytes 
aligned since we are using the GPU to scan the framebuffer of the guest 
(this could not be a limitation for different qemu backends).

The reason why the problem happen is that in the vesa driver, as it is 
now, has no way to detect the needed alignment of the framebuffer unless 
using the shadowFB.

The VBE (as I understand) has only two ways to say the driver what the 
stride should be for a given mode:

1) mode->BytesPerScanline
2) VBEGetLogicalScanline()

at the moment, in the vesa driver, the first information is only used 
when using the shadowFB:

     pMode = pScrn->modes;
     do {
         mode = ((VbeModeInfoData*)pMode->Private)->data;
         if (mode->BytesPerScanline > pVesa->maxBytesPerScanline) {
             pVesa->maxBytesPerScanline = mode->BytesPerScanline;
         }
         pMode = pMode->next;
     } while (pMode != pScrn->modes);

where

pVesa->maxBytesPerScanline

gets only used in VESAWindowLinear()

VESAWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
                  CARD32 *size, void *closure)
{
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     VESAPtr pVesa = VESAGetRec(pScrn);

     *size = pVesa->maxBytesPerScanline;
     return ((CARD8 *)pVesa->base + row * pVesa->maxBytesPerScanline + 
offset);
}

and as I said VESAWindowLinear() is used only if shadowFB is on

The second information is never used since VESASetMode() is only using 
VBESetLogicalScanline() and is never checking if the value was accepted 
from the HW or was rounded up and it looks like for mode 1366x768 
BytesPerScanline=5504, pScrn->displayWidth if 1368, which results in a 
scanline of 5472, which will result in a distorted image.

     if (data->data->XResolution != pScrn->displayWidth)
         VBESetLogicalScanline(pVesa->pVbe, pScrn->displayWidth);

The spec say that the HW could round up the value written with 
VBESetLogicalScanline() (and our emulation is doing so) so I think it 
would be appropriate to call VBEGetLogicalScanline() after to check if 
the value was accepted as it was or if it was rounded up, in which case 
pScrn->displayWidth and pScrn->virtualX should be updated accordingly.

If my understanding is correct, this would explain why when we disable 
shadowFB the actual stride is wrong.

If you can confirm my reasoning is correct, I would be happy to post a 
patch to fix this in case shadowFB is not used.

Thanks for your time,

Stefano

This is the mode creating problems:

[    99.232] *Mode: 156 (1366x768)
[    99.232]    ModeAttributes: 0x9b
[    99.232]    WinAAttributes: 0x7
[    99.232]    WinBAttributes: 0x0
[    99.232]    WinGranularity: 64
[    99.232]    WinSize: 64
[    99.232]    WinASegment: 0xa000
[    99.232]    WinBSegment: 0x0
[    99.232]    WinFuncPtr: 0xc000948a
[    99.232]    BytesPerScanline: 5504
[    99.232]    XResolution: 1366
[    99.232]    YResolution: 768
[    99.232]    XCharSize: 8
[    99.232]    YCharSize: 16
[    99.232]    NumberOfPlanes: 1
[    99.232]    BitsPerPixel: 32
[    99.232]    NumberOfBanks: 1
[    99.232]    MemoryModel: 6
[    99.232]    BankSize: 0
[    99.232]    NumberOfImages: 2
[    99.232]    RedMaskSize: 8
[    99.232]    RedFieldPosition: 16
[    99.232]    GreenMaskSize: 8
[    99.232]    GreenFieldPosition: 8
[    99.232]    BlueMaskSize: 8
[    99.232]    BlueFieldPosition: 0
[    99.232]    RsvdMaskSize: 8
[    99.232]    RsvdFieldPosition: 24
[    99.232]    DirectColorModeInfo: 2
[    99.232]    PhysBasePtr: 0xf0000000



More information about the xorg-devel mailing list