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