radeon driver (both 4.1.0 and CVS) have a problem with DGA 2.0.
17 weeks ago, I made a patch for radeon_dga.c and sent it to
[EMAIL PROTECTED]
David Dawes <[EMAIL PROTECTED]> sent me a response from radeon driver
maintainer. I read the comments, made a new patch and sent it to him.
He kindly submitted it to [EMAIL PROTECTED] more than 5 weeks ago.
But it's still pending.
So I'm posting my patch(A.585) to this mailing list.
I hope this is helpful to someone.
----
Shyouzou Sugitani <[EMAIL PROTECTED]>
<[EMAIL PROTECTED]>
--- xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c.dist Sun Sep 9
08:44:33 2001
+++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c Sun Sep 9 09:25:33
+2001
@@ -76,74 +76,68 @@
RADEONInfoPtr info = RADEONPTR(pScrn);
DGAModePtr newmodes = NULL, currentMode;
DisplayModePtr pMode, firstMode;
- int otherPitch, Bpp = bitsPerPixel >> 3;
+ int size, pitch, Bpp = bitsPerPixel >> 3;
Bool oneMore;
- pMode = firstMode = pScrn->modes;
-
- while (pMode) {
- otherPitch = secondPitch ? secondPitch : pMode->HDisplay;
-
- if (pMode->HDisplay != otherPitch) {
- newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec));
- oneMore = TRUE;
- } else {
- newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec));
- oneMore = FALSE;
- }
-
- if (!newmodes) {
- xfree(modes);
- return NULL;
- }
- modes = newmodes;
-
SECOND_PASS:
- currentMode = modes + *num;
- (*num)++;
+ pMode = firstMode = pScrn->modes;
- currentMode->mode = pMode;
- currentMode->flags = DGA_CONCURRENT_ACCESS;
- if (pixmap)
- currentMode->flags |= DGA_PIXMAP_AVAILABLE;
- if (info->accel) {
- if (info->accel->SetupForSolidFill &&
- info->accel->SubsequentSolidFillRect)
- currentMode->flags |= DGA_FILL_RECT;
- if (info->accel->SetupForScreenToScreenCopy &&
- info->accel->SubsequentScreenToScreenCopy)
- currentMode->flags |= DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS;
-
- if (currentMode->flags &
- (DGA_PIXMAP_AVAILABLE | DGA_FILL_RECT |
- DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS))
- currentMode->flags &= ~DGA_CONCURRENT_ACCESS;
- }
- if (pMode->Flags & V_DBLSCAN)
- currentMode->flags |= DGA_DOUBLESCAN;
- if (pMode->Flags & V_INTERLACE)
- currentMode->flags |= DGA_INTERLACED;
- currentMode->byteOrder = pScrn->imageByteOrder;
- currentMode->depth = depth;
- currentMode->bitsPerPixel = bitsPerPixel;
- currentMode->red_mask = red;
- currentMode->green_mask = green;
- currentMode->blue_mask = blue;
- currentMode->visualClass = visualClass;
- currentMode->viewportWidth = pMode->HDisplay;
- currentMode->viewportHeight = pMode->VDisplay;
- currentMode->xViewportStep = 8;
- currentMode->yViewportStep = 1;
- currentMode->viewportFlags = DGA_FLIP_RETRACE;
- currentMode->offset = 0;
- currentMode->address = (unsigned char*)info->LinearAddr;
-
- if (oneMore) { /* first one is narrow width */
- currentMode->bytesPerScanline = (((pMode->HDisplay * Bpp) + 3)
- & ~3L);
- currentMode->imageWidth = pMode->HDisplay;
- currentMode->imageHeight = pMode->VDisplay;
+ while (1) {
+ pitch = pScrn->displayWidth;
+ size = pitch * Bpp * pMode->VDisplay;
+
+ if ((!secondPitch || (pitch != secondPitch)) &&
+ (size <= info->FbMapSize)) {
+
+ if (secondPitch)
+ pitch = secondPitch;
+
+ if (!(newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec))))
+ break;
+
+ modes = newmodes;
+ currentMode = modes + *num;
+
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS;
+
+ if (pixmap)
+ currentMode->flags |= DGA_PIXMAP_AVAILABLE;
+
+ if (info->accel) {
+ if (info->accel->SetupForSolidFill &&
+ info->accel->SubsequentSolidFillRect)
+ currentMode->flags |= DGA_FILL_RECT;
+ if (info->accel->SetupForScreenToScreenCopy &&
+ info->accel->SubsequentScreenToScreenCopy)
+ currentMode->flags |= DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS;
+ if (currentMode->flags &
+ (DGA_PIXMAP_AVAILABLE | DGA_FILL_RECT |
+ DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS))
+ currentMode->flags &= ~DGA_CONCURRENT_ACCESS;
+ }
+ if (pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if (pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = depth;
+ currentMode->bitsPerPixel = bitsPerPixel;
+ currentMode->red_mask = red;
+ currentMode->green_mask = green;
+ currentMode->blue_mask = blue;
+ currentMode->visualClass = visualClass;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = 8;
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = 0;
+ currentMode->address = (unsigned char*)info->LinearAddr;
+ currentMode->bytesPerScanline = pitch * Bpp;
+ currentMode->imageWidth = pitch;
+ currentMode->imageHeight = info->FbMapSize /
+currentMode->bytesPerScanline;
currentMode->pixmapWidth = currentMode->imageWidth;
currentMode->pixmapHeight = currentMode->imageHeight;
currentMode->maxViewportX = currentMode->imageWidth -
@@ -151,24 +145,17 @@
/* this might need to get clamped to some maximum */
currentMode->maxViewportY = (currentMode->imageHeight -
currentMode->viewportHeight);
- oneMore = FALSE;
- goto SECOND_PASS;
- } else {
- currentMode->bytesPerScanline = ((otherPitch * Bpp) + 3) & ~3L;
- currentMode->imageWidth = otherPitch;
- currentMode->imageHeight = pMode->VDisplay;
- currentMode->pixmapWidth = currentMode->imageWidth;
- currentMode->pixmapHeight = currentMode->imageHeight;
- currentMode->maxViewportX = (currentMode->imageWidth -
- currentMode->viewportWidth);
- /* this might need to get clamped to some maximum */
- currentMode->maxViewportY = (currentMode->imageHeight -
- currentMode->viewportHeight);
+ (*num)++;
}
pMode = pMode->next;
if (pMode == firstMode)
break;
+ }
+
+ if (secondPitch) {
+ secondPitch = 0;
+ goto SECOND_PASS;
}
return modes;