summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--man/i810.man22
-rw-r--r--src/Makefile.am3
-rw-r--r--src/common.h77
-rw-r--r--src/i810.h4
-rw-r--r--src/i810_dri.c2
-rw-r--r--src/i810_driver.c10
-rw-r--r--src/i830.h49
-rw-r--r--src/i830_common.h29
-rw-r--r--src/i830_cursor.c153
-rw-r--r--src/i830_dga.c116
-rw-r--r--src/i830_dri.c371
-rw-r--r--src/i830_dri.h10
-rw-r--r--src/i830_driver.c1159
-rw-r--r--src/i830_memory.c542
-rw-r--r--src/i830_modes.c2
-rw-r--r--src/i830_randr.c356
-rw-r--r--src/i830_rotate.c1181
-rw-r--r--src/i830_shadow.c253
-rw-r--r--src/i830_video.c869
20 files changed, 4038 insertions, 1172 deletions
diff --git a/configure.ac b/configure.ac
index e50b3d18..665b76a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
AC_PREREQ(2.57)
AC_INIT([xf86-video-i810],
- 1.4.1.3,
+ 1.5.0.0,
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
xf86-video-i810)
diff --git a/man/i810.man b/man/i810.man
index 8c432eff..099e1f8a 100644
--- a/man/i810.man
+++ b/man/i810.man
@@ -192,16 +192,18 @@ the machine has booted, but unfortunately it doesn't always work and
is extremely dependent upon the Video BIOS.
Default: disabled
.TP
-.BI "Option \*qRotate\*q \*qCW\*q"
-.TP
-.BI "Option \*qRotate\*q \*qCCW\*q"
-Rotate the desktop 90 degrees clockwise or counterclockwise. This option
-forces the ShadowFB option on, and disables acceleration.
-Default: no rotation.
-.TP
-.BI "Option \*qShadowFB\*q \*q" boolean \*q
-Enable or disable use of the shadow framebuffer layer. This option
-disables acceleration. Default: off.
+.BI "Option \*qRotate\*q \*q90\*q"
+Rotate the desktop 90 degrees counterclockwise. Other valid options are
+0, 90, 180 and 270 degrees. The RandR extension is used for rotation
+functionality. So this option allows the Xserver to start with a rotated
+mode of operation.
+Default: 0 degrees.
+.TP
+.BI "Option \*qLinearAlloc\*q \*q" integer \*q
+Allows more memory for the offscreen allocator. This usually helps in
+situations where HDTV movies are required to play but not enough offscreen
+memory is usually available. Set this to 6144 for upto 1920x1080 HDTV support.
+Default 0KB (off).
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
diff --git a/src/Makefile.am b/src/Makefile.am
index fa695928..c64c2036 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,7 +53,8 @@ i810_drv_la_SOURCES = \
i830_memory.c \
i830_modes.c \
i830_video.c \
- i830_shadow.c
+ i830_rotate.c \
+ i830_randr.c
if DRI
i810_drv_la_SOURCES += \
diff --git a/src/common.h b/src/common.h
index 85a24ab3..bb89dd25 100644
--- a/src/common.h
+++ b/src/common.h
@@ -119,29 +119,21 @@ extern void I830DPRINTF_stub(const char *filename, int line,
ErrorF( "OUT_RING %lx: %x, (mask %x)\n", \
(unsigned long)(outring), (unsigned int)(n), ringmask); \
*(volatile unsigned int *)(virt + outring) = n; \
- outring += 4; \
+ outring += 4; ringused += 4; \
outring &= ringmask; \
} while (0)
-#if 1
#define ADVANCE_LP_RING() do { \
+ if (ringused > needed) \
+ ErrorF("%s: ADVANCE_LP_RING: exceeded allocation %d/%d\n ", \
+ __FUNCTION__, ringused, needed); \
RecPtr->LpRing->tail = outring; \
+ RecPtr->LpRing->space -= ringused; \
if (outring & 0x07) \
ErrorF("ADVANCE_LP_RING: " \
"outring (0x%x) isn't on a QWord boundary", outring); \
OUTREG(LP_RING + RING_TAIL, outring); \
} while (0)
-#else
-#define ADVANCE_LP_RING() { \
- RecPtr->LpRing->tail = outring; \
- if (outring & 0x07) \
- ErrorF("ADVANCE_LP_RING: " \
- "outring (0x%x) isn't on a QWord boundary", outring); \
- ErrorF("head is %d, tail is %d [%d]\n", INREG(LP_RING + RING_HEAD), INREG(LP_RING + RING_TAIL), outring); \
- OUTREG(LP_RING + RING_TAIL, outring); \
- ErrorF("head is %d, tail is %d [%d]\n", INREG(LP_RING + RING_HEAD), INREG(LP_RING + RING_TAIL), outring); \
-}
-#endif
/*
* XXX Note: the head/tail masks are different for 810 and i830.
@@ -158,54 +150,9 @@ extern void I830DPRINTF_stub(const char *filename, int line,
} while (_head != _tail); \
} while( 0)
-/*
- * This is for debugging a potential problem writing the tail pointer
- * close to the end of the ring buffer.
- */
-#ifndef AVOID_TAIL_END
-#define AVOID_TAIL_END 0
-#endif
-#ifndef AVOID_SIZE
-#define AVOID_SIZE 64
-#endif
-
-#if AVOID_TAIL_END
-
-#define BEGIN_LP_RING(n) \
- unsigned int outring, ringmask; \
- volatile unsigned char *virt; \
- int needed; \
- if ((n) & 1) \
- ErrorF("BEGIN_LP_RING called with odd argument: %d\n", n); \
- if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \
- DO_RING_IDLE(); \
- needed = (n) * 4; \
- if ((RecPtr->LpRing->tail > RecPtr->LpRing->tail_mask - AVOID_SIZE) || \
- (RecPtr->LpRing->tail + needed) > \
- RecPtr->LpRing->tail_mask - AVOID_SIZE) { \
- needed += RecPtr->LpRing->tail_mask + 1 - RecPtr->LpRing->tail; \
- ErrorF("BEGIN_LP_RING: skipping last 64 bytes of " \
- "ring (%d vs %d)\n", needed, (n) * 4); \
- } \
- if (RecPtr->LpRing->space < needed) \
- WaitRingFunc(pScrn, needed, 0); \
- RecPtr->LpRing->space -= needed; \
- outring = RecPtr->LpRing->tail; \
- ringmask = RecPtr->LpRing->tail_mask; \
- virt = RecPtr->LpRing->virtual_start; \
- while (needed > (n) * 4) { \
- ErrorF("BEGIN_LP_RING: putting MI_NOOP at 0x%x (remaining %d)\n", \
- outring, needed - (n) * 4); \
- OUT_RING(MI_NOOP); \
- needed -= 4; \
- } \
- if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME);
-
-#else /* AVOID_TAIL_END */
#define BEGIN_LP_RING(n) \
- unsigned int outring, ringmask; \
+ unsigned int outring, ringmask, ringused = 0; \
volatile unsigned char *virt; \
int needed; \
if ((n) & 1) \
@@ -215,14 +162,12 @@ extern void I830DPRINTF_stub(const char *filename, int line,
needed = (n) * 4; \
if (RecPtr->LpRing->space < needed) \
WaitRingFunc(pScrn, needed, 0); \
- RecPtr->LpRing->space -= needed; \
outring = RecPtr->LpRing->tail; \
ringmask = RecPtr->LpRing->tail_mask; \
virt = RecPtr->LpRing->virtual_start; \
if (I810_DEBUG & DEBUG_VERBOSE_RING) \
ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME);
-#endif /* AVOID_TAIL_END */
/* Memory mapped register access macros */
@@ -322,6 +267,11 @@ extern int I810_DEBUG;
#define PCI_CHIP_I945_G_BRIDGE 0x2770
#endif
+#ifndef PCI_CHIP_I945_GM
+#define PCI_CHIP_I945_GM 0x27A2
+#define PCI_CHIP_I945_GM_BRIDGE 0x27A0
+#endif
+
#define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 || \
pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
pI810->PciInfo->chipType == PCI_CHIP_I810_E)
@@ -332,11 +282,14 @@ extern int I810_DEBUG;
#define IS_I852(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME))
#define IS_I855(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME))
#define IS_I865G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I865_G)
+
#define IS_I915G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_G || pI810->PciInfo->chipType == PCI_CHIP_E7221_G)
#define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
#define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
+#define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM)
+#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810))
-#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810))
+#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810))
#define GTT_PAGE_SIZE KB(4)
#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y))
diff --git a/src/i810.h b/src/i810.h
index 198f0eca..a1ed9f27 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -66,8 +66,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I810_NAME "I810"
#define I810_DRIVER_NAME "i810"
#define I810_MAJOR_VERSION 1
-#define I810_MINOR_VERSION 4
-#define I810_PATCHLEVEL 1
+#define I810_MINOR_VERSION 5
+#define I810_PATCHLEVEL 0
/* HWMC Surfaces */
diff --git a/src/i810_dri.c b/src/i810_dri.c
index f9b95bdc..82fb0594 100644
--- a/src/i810_dri.c
+++ b/src/i810_dri.c
@@ -356,7 +356,7 @@ I810DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION;
pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION;
pDRIInfo->ddxDriverPatchVersion = I810_PATCHLEVEL;
- pDRIInfo->frameBufferPhysicalAddress = pI810->LinearAddr;
+ pDRIInfo->frameBufferPhysicalAddress = (pointer) pI810->LinearAddr;
pDRIInfo->frameBufferSize = (((pScrn->displayWidth *
pScrn->virtualY * pI810->cpp) +
4096 - 1) / 4096) * 4096;
diff --git a/src/i810_driver.c b/src/i810_driver.c
index bfa1dae9..54395a78 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -136,6 +136,7 @@ static SymTabRec I810Chipsets[] = {
{PCI_CHIP_E7221_G, "E7221 (i915)"},
{PCI_CHIP_I915_GM, "915GM"},
{PCI_CHIP_I945_G, "945G"},
+ {PCI_CHIP_I945_GM, "945GM"},
{-1, NULL}
};
@@ -154,6 +155,7 @@ static PciChipsets I810PciChipsets[] = {
{PCI_CHIP_E7221_G, PCI_CHIP_E7221_G, RES_SHARED_VGA},
{PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, RES_SHARED_VGA},
{PCI_CHIP_I945_G, PCI_CHIP_I945_G, RES_SHARED_VGA},
+ {PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED }
};
@@ -299,6 +301,7 @@ const char *I810drmSymbols[] = {
"drmGetInterruptFromBusID",
"drmGetLibVersion",
"drmGetVersion",
+ "drmRmMap",
NULL
};
@@ -306,6 +309,7 @@ const char *I810drmSymbols[] = {
const char *I810driSymbols[] = {
"DRICloseScreen",
"DRICreateInfoRec",
+ "DRIGetContext",
"DRIDestroyInfoRec",
"DRIFinishScreenInit",
"DRIGetSAREAPrivate",
@@ -317,16 +321,17 @@ const char *I810driSymbols[] = {
"DRICreatePCIBusID",
NULL
};
+#endif
const char *I810shadowSymbols[] = {
"shadowInit",
"shadowSetup",
"shadowAdd",
+ "shadowRemove",
+ "shadowUpdateRotatePacked",
NULL
};
-#endif
-
#ifndef I810_DEBUG
int I810_DEBUG = (0
/* | DEBUG_ALWAYS_SYNC */
@@ -569,6 +574,7 @@ I810Probe(DriverPtr drv, int flags)
case PCI_CHIP_E7221_G:
case PCI_CHIP_I915_GM:
case PCI_CHIP_I945_G:
+ case PCI_CHIP_I945_GM:
xf86SetEntitySharable(usedChips[i]);
/* Allocate an entity private if necessary */
diff --git a/src/i830.h b/src/i830.h
index eef28e79..11695a20 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -58,6 +58,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86int10.h"
#include "vbe.h"
#include "vgaHW.h"
+#include "randrstr.h"
#ifdef XF86DRI
#include "xf86drm.h"
@@ -168,6 +169,8 @@ typedef struct _I830Rec {
int fixedPipe;
+ DisplayModePtr currentMode;
+
Bool Clone;
int CloneRefresh;
int CloneHDisplay;
@@ -214,14 +217,25 @@ typedef struct _I830Rec {
#ifdef I830_XV
/* For Xvideo */
I830MemRange *OverlayMem;
+ I830MemRange LinearMem;
#endif
+ unsigned int LinearAlloc;
+
+ I830MemRange RotatedMem;
+ I830MemRange RotatedMem2;
+ Rotation rotation;
+ int InitialRotation;
+ int displayWidth;
+ void (*PointerMoved)(int, int, int);
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ int *used3D;
#ifdef XF86DRI
I830MemRange BackBuffer;
I830MemRange DepthBuffer;
I830MemRange TexMem;
- I830MemRange ContextMem;
int TexGranularity;
+ I830MemRange ContextMem;
int drmMinor;
Bool have3DWindows;
#endif
@@ -234,6 +248,7 @@ typedef struct _I830Rec {
Bool CursorNeedsPhysical;
Bool CursorIsARGB;
+ CursorPtr pCurs;
int MonType1;
int MonType2;
@@ -303,13 +318,6 @@ typedef struct _I830Rec {
/* Broken-out options. */
OptionInfoPtr Options;
- int rotate;
- Bool shadowFB;
-
- /* Support for shadowFB and rotation. */
- unsigned char *shadowPtr;
- int shadowPitch;
- void (*PointerMoved)(int, int, int);
/* Stolen memory support */
Bool StolenOnly;
@@ -335,8 +343,9 @@ typedef struct _I830Rec {
Bool checkDevices;
int monitorSwitch;
int operatingDevices;
+ int toggleDevices;
int savedDevices;
- int lastDevice1, lastDevice2;
+ int lastDevice0, lastDevice1, lastDevice2;
/* These are indexed by the display types */
Bool displayAttached[NumDisplayTypes];
@@ -399,15 +408,27 @@ extern void I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode);
extern void I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode);
#endif
+extern Bool I830AllocateRotatedBuffer(ScrnInfoPtr pScrn, const int flags);
+extern Bool I830AllocateRotated2Buffer(ScrnInfoPtr pScrn, const int flags);
#ifdef XF86DRI
extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags);
+extern Bool I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags);
+extern Bool I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags);
+extern Bool I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags);
extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn);
extern Bool I830DRIScreenInit(ScreenPtr pScreen);
+extern Bool I830CheckDRIAvailable(ScrnInfoPtr pScrn);
extern Bool I830DRIDoMappings(ScreenPtr pScreen);
extern Bool I830DRIResume(ScreenPtr pScreen);
extern void I830DRICloseScreen(ScreenPtr pScreen);
extern Bool I830DRIFinishScreenInit(ScreenPtr pScreen);
+extern Bool I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea);
+extern void I830DRIUnmapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea);
+extern Bool I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea);
+extern void I830DRIUnlock(ScrnInfoPtr pScrn);
+extern Bool I830DRILock(ScrnInfoPtr pScrn);
#endif
+
extern Bool I830AccelInit(ScreenPtr pScreen);
extern void I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
int ydir, int rop,
@@ -432,11 +453,13 @@ extern Bool I830UnbindGARTMemory(ScrnInfoPtr pScrn);
extern unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result,
I830MemPool *pool, long size,
unsigned long alignment, int flags);
+extern void I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range);
extern void I830PrintAllRegisters(I830RegPtr i830Reg);
extern void I830ReadAllRegisters(I830Ptr pI830, I830RegPtr i830Reg);
extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer);
+extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
extern DisplayModePtr I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe,
VbeInfoBlock *vbe);
@@ -445,12 +468,8 @@ extern void I830UnsetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
extern void I830PrintModes(ScrnInfoPtr pScrn);
extern int I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh);
extern Bool I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode);
-extern void I830PointerMoved(int index, int x, int y);
-extern void I830RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
-extern void I830RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
-extern void I830RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
-extern void I830RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
-extern void I830RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+extern Bool I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode);
+extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
/*
* 12288 is set as the maximum, chosen because it is enough for
diff --git a/src/i830_common.h b/src/i830_common.h
index a0a00ff4..41b5cc3c 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -51,6 +51,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DRM_I830_FREE 0x09
#define DRM_I830_INIT_HEAP 0x0a
#define DRM_I830_CMDBUFFER 0x0b
+#define DRM_I830_DESTROY_HEAP 0x0c
typedef struct {
enum {
@@ -87,6 +88,30 @@ typedef struct {
int pf_active;
int pf_current_page; /* which buffer is being displayed? */
int perf_boxes; /* performance boxes to be displayed */
+ int width, height; /* screen size in pixels */
+
+ drm_handle_t front_handle;
+ int front_offset;
+ int front_size;
+
+ drm_handle_t back_handle;
+ int back_offset;
+ int back_size;
+
+ drm_handle_t depth_handle;
+ int depth_offset;
+ int depth_size;
+
+ drm_handle_t tex_handle;
+ int tex_offset;
+ int tex_size;
+ int log_tex_granularity;
+ int pitch;
+ int rotation; /* 0, 90, 180 or 270 */
+ int rotated_offset;
+ int rotated_size;
+ int rotated_pitch;
+ int virtualX, virtualY;
} drmI830Sarea;
/* Flags for perf_boxes
@@ -164,5 +189,9 @@ typedef struct {
int start;
} drmI830MemInitHeap;
+typedef struct {
+ int region;
+} drmI830MemDestroyHeap;
+
#endif /* _I830_DRM_H_ */
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 24114192..dfed8cda 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -86,12 +86,14 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
DPRINTF(PFX, "I830InitHWCursor\n");
/* Initialise the HW cursor registers, leaving the cursor hidden. */
- if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) {
+ if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL |
MCURSOR_PIPE_SELECT);
temp |= CURSOR_MODE_DISABLE;
temp |= (pI830->pipe << 28);
+ if(pI830->CursorIsARGB)
+ temp |= MCURSOR_GAMMA_ENABLE;
/* Need to set control, then address. */
OUTREG(CURSOR_A_CONTROL, temp);
if (pI830->CursorIsARGB)
@@ -139,8 +141,8 @@ I830CursorInit(ScreenPtr pScreen)
if (!infoPtr)
return FALSE;
- infoPtr->MaxWidth = 64;
- infoPtr->MaxHeight = 64;
+ infoPtr->MaxWidth = I810_CURSOR_X;
+ infoPtr->MaxHeight = I810_CURSOR_Y;
infoPtr->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
HARDWARE_CURSOR_INVERT_MASK |
@@ -155,6 +157,8 @@ I830CursorInit(ScreenPtr pScreen)
infoPtr->ShowCursor = I830ShowCursor;
infoPtr->UseHWCursor = I830UseHWCursor;
+ pI830->pCurs = NULL;
+
#ifdef ARGB_CURSOR
pI830->CursorIsARGB = FALSE;
@@ -179,6 +183,8 @@ I830UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
+ pI830->pCurs = pCurs;
+
DPRINTF(PFX, "I830UseHWCursor\n");
if (pI830->CursorNeedsPhysical && !pI830->CursorMem->Physical)
return FALSE;
@@ -198,6 +204,52 @@ I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
#ifdef ARGB_CURSOR
pI830->CursorIsARGB = FALSE;
#endif
+
+ memset(pcurs, 0, 64 * 64 / 4);
+
+#define GetBit(image, x, y)\
+ ((int)((*(image + ((x) / 8) + ((y) * (128/8))) &\
+ (1 << ( 7 -((x) % 8) ))) ? 1 : 0))
+
+#define SetBit(image, x, y)\
+ (*(image + (x) / 8 + (y) * (128/8)) |=\
+ (int) (1 << (7-((x) % 8))))
+
+ switch (pI830->rotation) {
+ case RR_Rotate_90:
+ for (y = 0; y < 64; y++) {
+ for (x = 0; x < 64; x++) {
+ if (GetBit(src, 64 - y - 1, x))
+ SetBit(pcurs, x, y);
+ if (GetBit(src, 128 - y - 1, x))
+ SetBit(pcurs, x + 64, y);
+ }
+ }
+
+ return;
+ case RR_Rotate_180:
+ for (y = 0; y < 64; y++) {
+ for (x = 0; x < 64; x++) {
+ if (GetBit(src, 64 - x - 1, 64 - y - 1))
+ SetBit(pcurs, x, y);
+ if (GetBit(src, 128 - x - 1, 64 - y - 1))
+ SetBit(pcurs, x + 64, y);
+ }
+ }
+
+ return;
+ case RR_Rotate_270:
+ for (y = 0; y < 64; y++) {
+ for (x = 0; x < 64; x++) {
+ if (GetBit(src, y, 64 - x - 1))
+ SetBit(pcurs, x, y);
+ if (GetBit(src, y + 64, 64 - x - 1))
+ SetBit(pcurs, x + 64, y);
+ }
+ }
+
+ return;
+ }
for (y = 0; y < 64; y++) {
for (x = 0; x < 64 / 4; x++) {
@@ -215,6 +267,9 @@ static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX, "I830UseHWCursorARGB\n");
+
+ pI830->pCurs = pCurs;
+
if (pScrn->bitsPerPixel == 8)
return FALSE;
@@ -239,13 +294,52 @@ static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
if (!image)
return; /* XXX can't happen */
-#ifdef ARGB_CURSOR
pI830->CursorIsARGB = TRUE;
-#endif
w = pCurs->bits->width;
h = pCurs->bits->height;
+ switch (pI830->rotation) {
+ case RR_Rotate_90:
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++)
+ dst[(y) + ((64 - x - 1) * 64)] = *image++;
+ for(; x < 64; x++)
+ dst[(y) + ((64 - x - 1) * 64)] = 0;
+ }
+ for(; y < 64; y++) {
+ for(x = 0; x < 64; x++)
+ dst[(y) + ((64 - x - 1) * 64)] = 0;
+ }
+ return;
+
+ case RR_Rotate_180:
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++)
+ dst[(64 - x - 1) + ((64 - y - 1) * 64)] = *image++;
+ for(; x < 64; x++)
+ dst[(64 - x - 1) + ((64 - y - 1) * 64)] = 0;
+ }
+ for(; y < 64; y++) {
+ for(x = 0; x < 64; x++)
+ dst[(64 - x - 1) + ((64 - y - 1) * 64)] = 0;
+ }
+ return;
+
+ case RR_Rotate_270:
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++)
+ dst[(64 - y - 1) + (x * 64)] = *image++;
+ for(; x < 64; x++)
+ dst[(64 - y - 1) + (x * 64)] = 0;
+ }
+ for(; y < 64; y++) {
+ for(x = 0; x < 64; x++)
+ dst[(64 - y - 1) + (x * 64)] = 0;
+ }
+ return;
+ }
+
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++)
*dst++ = *image++;
@@ -267,7 +361,49 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
CARD32 temp = 0;
static Bool outsideViewport = FALSE;
Bool hide = FALSE, show = FALSE;
+ int oldx = x, oldy = y;
+ int hotspotx = 0, hotspoty = 0;
+
+ oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
+ oldy += pScrn->frameY0;
+
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ x = oldx;
+ y = oldy;
+ break;
+ case RR_Rotate_90:
+ x = oldy;
+ y = pScrn->pScreen->width - oldx;
+ hotspoty = I810_CURSOR_X;
+ break;
+ case RR_Rotate_180:
+ x = pScrn->pScreen->width - oldx;
+ y = pScrn->pScreen->height - oldy;
+ hotspotx = I810_CURSOR_X;
+ hotspoty = I810_CURSOR_Y;
+ break;
+ case RR_Rotate_270:
+ x = pScrn->pScreen->height - oldy;
+ y = oldx;
+ hotspotx = I810_CURSOR_Y;
+ break;
+ }
+
+ x -= hotspotx;
+ y -= hotspoty;
+ /* Now, readjust */
+ x -= pScrn->frameX0;
+ y -= pScrn->frameY0;
+
+ /* Clamp the cursor position to the visible screen area */
+ if (x >= pScrn->currentMode->HDisplay) x = pScrn->currentMode->HDisplay - 1;
+ if (y >= pScrn->currentMode->VDisplay) y = pScrn->currentMode->VDisplay - 1;
+ if (x <= -I810_CURSOR_X) x = -I810_CURSOR_X + 1;
+ if (y <= -I810_CURSOR_Y) y = -I810_CURSOR_Y + 1;
+
+#if 0
/*
* There is a screen display problem when the cursor position is set
* wholely outside of the viewport. We trap that here, turning the
@@ -283,6 +419,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
show = TRUE;
outsideViewport = FALSE;
}
+#endif
if (x < 0) {
temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
@@ -308,7 +445,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
}
/* have to upload the base for the new position */
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
+ if (IS_I9XX(pI830)) {
if (pI830->CursorIsARGB)
OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
else
@@ -339,7 +476,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
pI830->cursorOn = TRUE;
- if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) {
+ if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
if (pI830->CursorIsARGB)
@@ -387,7 +524,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
DPRINTF(PFX, "I830HideCursor\n");
pI830->cursorOn = FALSE;
- if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) {
+ if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
temp &= ~CURSOR_MODE;
temp |= CURSOR_MODE_DISABLE;
diff --git a/src/i830_dga.c b/src/i830_dga.c
index e1991db4..e5bcfc72 100644
--- a/src/i830_dga.c
+++ b/src/i830_dga.c
@@ -54,6 +54,7 @@
static Bool I830_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
int *, int *, int *);
+static void I830_CloseFramebuffer(ScrnInfoPtr pScrn);
static Bool I830_SetMode(ScrnInfoPtr, DGAModePtr);
static void I830_Sync(ScrnInfoPtr);
static int I830_GetViewport(ScrnInfoPtr);
@@ -69,7 +70,7 @@ static void I830_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
static
DGAFunctionRec I830DGAFuncs = {
I830_OpenFramebuffer,
- NULL,
+ I830_CloseFramebuffer,
I830_SetMode,
I830_SetViewport,
I830_GetViewport,
@@ -131,11 +132,22 @@ I830DGAInit(ScreenPtr pScreen)
currentMode->yViewportStep = 1;
currentMode->viewportFlags = DGA_FLIP_RETRACE;
currentMode->offset = 0;
- currentMode->address = pI830->FbBase + pScrn->fbOffset;
+ if (I830IsPrimary(pScrn)) {
+ currentMode->address = pI830->FbBase + pI830->FrontBuffer.Start;
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ currentMode->address = pI830->FbBase + pI8301->FrontBuffer2.Start;
+ }
- currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L;
- currentMode->imageWidth = pI830->FbMemBox.x2;
- currentMode->imageHeight = pI830->FbMemBox.y2;
+ currentMode->bytesPerScanline = ((pI830->displayWidth * Bpp) + 3) & ~3L;
+ if (I830IsPrimary(pScrn)) {
+ currentMode->imageWidth = pI830->FbMemBox.x2;
+ currentMode->imageHeight = pI830->FbMemBox.y2;
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ currentMode->imageWidth = pI8301->FbMemBox2.x2;
+ currentMode->imageHeight = pI8301->FbMemBox2.y2;
+ }
currentMode->pixmapWidth = currentMode->imageWidth;
currentMode->pixmapHeight = currentMode->imageHeight;
currentMode->maxViewportX = currentMode->imageWidth -
@@ -168,6 +180,7 @@ I830_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
if (!pMode) { /* restore the original mode */
DPRINTF(PFX, "Restoring original mode (from DGA mode)\n");
if (pI830->DGAactive) {
+ I830_CloseFramebuffer(pScrn);
pScrn->currentMode = I830SavedDGAModes[index];
pScrn->SwitchMode(index, pScrn->currentMode, 0);
pScrn->AdjustFrame(index, 0, 0, 0);
@@ -178,6 +191,15 @@ I830_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
DPRINTF(PFX, "Setting DGA mode\n");
I830SavedDGAModes[index] = pScrn->currentMode;
pI830->DGAactive = TRUE;
+ if (I830IsPrimary(pScrn)) {
+ pScrn->fbOffset = pI830->FrontBuffer.Start;
+ }
+ else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pScrn->fbOffset = pI8301->FrontBuffer2.Start;
+ }
+ pScrn->displayWidth = pI830->displayWidth;
+ I830SelectBuffer(pScrn, I830_SELECT_FRONT);
}
pScrn->SwitchMode(index, pMode->mode, 0);
@@ -284,13 +306,19 @@ I830_OpenFramebuffer(ScrnInfoPtr pScrn,
MARKER();
*name = NULL; /* no special device */
- *mem = (unsigned char *)(pI830->LinearAddr + pScrn->fbOffset);
- if (pI830->init == 0)
+ if (I830IsPrimary(pScrn)) {
*size = pI830->FrontBuffer.Size;
+ *mem = (unsigned char *)(pI830->LinearAddr + pI830->FrontBuffer.Start);
+ pScrn->fbOffset = pI830->FrontBuffer.Start;
+ }
else {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
*size = pI8301->FrontBuffer2.Size;
+ *mem = (unsigned char *)(pI8301->LinearAddr + pI8301->FrontBuffer2.Start);
+ pScrn->fbOffset = pI8301->FrontBuffer2.Start;
}
+ pScrn->displayWidth = pI830->displayWidth;
+ I830SelectBuffer(pScrn, I830_SELECT_FRONT);
*offset = 0;
*flags = DGA_NEED_ROOT;
@@ -300,3 +328,77 @@ I830_OpenFramebuffer(ScrnInfoPtr pScrn,
return TRUE;
}
+
+static void
+I830_CloseFramebuffer(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ int i;
+ /* Good pitches to allow tiling. Don't care about pitches < 1024. */
+ static const int pitches[] = {
+/*
+ 128 * 2,
+ 128 * 4,
+*/
+ 128 * 8,
+ 128 * 16,
+ 128 * 32,
+ 128 * 64,
+ 0
+ };
+
+ if (I830IsPrimary(pScrn)) {
+ if (pI830->rotation != RR_Rotate_0)
+ pScrn->fbOffset = pI830->RotatedMem.Start;
+ else
+ pScrn->fbOffset = pI830->FrontBuffer.Start;
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+
+ if (pI830->rotation != RR_Rotate_0)
+ pScrn->fbOffset = pI8301->RotatedMem2.Start;
+ else
+ pScrn->fbOffset = pI8301->FrontBuffer2.Start;
+ }
+ I830SelectBuffer(pScrn, I830_SELECT_FRONT);
+
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ pScrn->displayWidth = pI830->displayWidth;
+ break;
+ case RR_Rotate_90:
+ pScrn->displayWidth = pScrn->pScreen->width;
+ break;
+ case RR_Rotate_180:
+ pScrn->displayWidth = pI830->displayWidth;
+ break;
+ case RR_Rotate_270:
+ pScrn->displayWidth = pScrn->pScreen->width;
+ break;
+ }
+
+ /* As DRI doesn't run on the secondary head, we know that disableTiling
+ * is always TRUE.
+ */
+ if (I830IsPrimary(pScrn) && !pI830->disableTiling) {
+#if 0
+ int dWidth = pScrn->displayWidth; /* save current displayWidth */
+#endif
+
+ for (i = 0; pitches[i] != 0; i++) {
+ if (pitches[i] >= pScrn->displayWidth) {
+ pScrn->displayWidth = pitches[i];
+ break;
+ }
+ }
+
+ /*
+ * If the displayWidth is a tilable pitch, test if there's enough
+ * memory available to enable tiling.
+ */
+ if (pScrn->displayWidth == pitches[i]) {
+ /* TODO */
+ }
+ }
+
+}
diff --git a/src/i830_dri.c b/src/i830_dri.c
index ade0c0ce..c2e060fc 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -149,9 +149,9 @@ I830InitDma(ScrnInfoPtr pScrn)
info.depth_offset = pI830->DepthBuffer.Start;
info.w = pScrn->virtualX;
info.h = pScrn->virtualY;
- info.pitch = pI830->backPitch;
- info.back_pitch = pI830->backPitch;
- info.depth_pitch = pI830->backPitch;
+ info.pitch = pI830->displayWidth;
+ info.back_pitch = pI830->displayWidth;
+ info.depth_pitch = pI830->displayWidth;
info.cpp = pI830->cpp;
if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT,
@@ -405,18 +405,12 @@ I830InitVisualConfigs(ScreenPtr pScreen)
}
Bool
-I830DRIScreenInit(ScreenPtr pScreen)
+I830CheckDRIAvailable(ScrnInfoPtr pScrn)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- I830Ptr pI830 = I830PTR(pScrn);
- DRIInfoPtr pDRIInfo;
- I830DRIPtr pI830DRI;
-
- DPRINTF(PFX, "I830DRIScreenInit\n");
/* Hardware 3D rendering only implemented for 16bpp and 32 bpp */
if (((pScrn->bitsPerPixel / 8) != 2 && pScrn->depth != 16) &&
(pScrn->bitsPerPixel / 8) != 4) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] Direct rendering only supported in 16 and 32 bpp modes\n");
return FALSE;
}
@@ -428,7 +422,7 @@ I830DRIScreenInit(ScreenPtr pScreen)
if (!xf86LoaderCheckSymbol("drmAvailable"))
return FALSE;
if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] %s failed (libdri.a too old)\n", "I830DRIScreenInit");
return FALSE;
}
@@ -439,7 +433,7 @@ I830DRIScreenInit(ScreenPtr pScreen)
DRIQueryVersion(&major, &minor, &patch);
if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] %s failed because of a version mismatch.\n"
"[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n"
"[dri] Disabling DRI.\n",
@@ -449,6 +443,22 @@ I830DRIScreenInit(ScreenPtr pScreen)
}
}
+ return TRUE;
+}
+
+Bool
+I830DRIScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ DRIInfoPtr pDRIInfo;
+ I830DRIPtr pI830DRI;
+
+ DPRINTF(PFX, "I830DRIScreenInit\n");
+
+ if (!I830CheckDRIAvailable(pScrn))
+ return FALSE;
+
pDRIInfo = DRICreateInfoRec();
if (!pDRIInfo) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
@@ -473,10 +483,15 @@ I830DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION;
pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION;
pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL;
- pDRIInfo->frameBufferPhysicalAddress = pI830->LinearAddr +
+ pDRIInfo->frameBufferPhysicalAddress = (pointer) pI830->LinearAddr +
pI830->FrontBuffer.Start;
+#if 0
pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
pScrn->virtualY * pI830->cpp);
+#else
+ /* For rotation we map a 0 length framebuffer as we remap ourselves later */
+ pDRIInfo->frameBufferSize = 0;
+#endif
pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp;
pDRIInfo->ddxDrawableTableEntry = I830_MAX_DRAWABLES;
@@ -572,11 +587,11 @@ I830DRIScreenInit(ScreenPtr pScreen)
/* Check the i915 DRM version */
version = drmGetVersion(pI830->drmSubFD);
if (version) {
- if (version->version_major != 1 || version->version_minor < 1) {
+ if (version->version_major != 1 || version->version_minor < 4) {
/* incompatible drm version */
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[dri] %s failed because of a version mismatch.\n"
- "[dri] i915 kernel module version is %d.%d.%d but version 1.1 or greater is needed.\n"
+ "[dri] i915 kernel module version is %d.%d.%d but version 1.4 or greater is needed.\n"
"[dri] Disabling DRI.\n",
"I830DRIScreenInit",
version->version_major,
@@ -601,57 +616,136 @@ I830DRIScreenInit(ScreenPtr pScreen)
}
Bool
-I830DRIDoMappings(ScreenPtr pScreen)
+I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ScreenPtr pScreen = pScrn->pScreen;
I830Ptr pI830 = I830PTR(pScrn);
- DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
- I830DRIPtr pI830DRI = pDRIInfo->devPrivate;
- DPRINTF(PFX, "I830DRIDoMappings\n");
- pI830DRI->regsSize = I830_REG_SIZE;
- if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr,
- pI830DRI->regsSize, DRM_REGISTERS, 0, &pI830DRI->regs) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] Mapping front buffer\n");
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
+ sarea->front_size,
+ DRM_FRAME_BUFFER, /*DRM_AGP,*/
+ 0,
+ &sarea->front_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(front_handle) failed. Disabling DRI\n");
DRICloseScreen(pScreen);
return FALSE;
}
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n",
- pI830DRI->regs);
-
- /*
- * The tile setup is now initiated from I830BIOSScreenInit().
- */
-
- pI830->backPitch = pScrn->displayWidth;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08lx\n",
+ sarea->front_handle);
- pI830DRI->backbufferSize = pI830->BackBuffer.Size;
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(sarea->back_offset + pI830->LinearAddr),
+ sarea->back_size, DRM_AGP, 0,
+ &sarea->back_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(back_handle) failed. Disabling DRI\n");
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Back Buffer = 0x%08lx\n",
+ sarea->back_handle);
if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)pI830->BackBuffer.Start + pI830->LinearAddr,
- pI830->BackBuffer.Size, DRM_AGP, 0,
- &pI830DRI->backbuffer) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n");
+ (drm_handle_t)sarea->depth_offset + pI830->LinearAddr,
+ sarea->depth_size, DRM_AGP, 0,
+ &sarea->depth_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n");
DRICloseScreen(pScreen);
return FALSE;
}
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Back Buffer = 0x%08x\n",
- pI830DRI->backbuffer);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Depth Buffer = 0x%08lx\n",
+ sarea->depth_handle);
- pI830DRI->depthbufferSize = pI830->DepthBuffer.Size;
if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)pI830->DepthBuffer.Start + pI830->LinearAddr,
- pI830->DepthBuffer.Size, DRM_AGP, 0,
- &pI830DRI->depthbuffer) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] drmAddMap(depthbuffer) failed. Disabling DRI\n");
+ (drm_handle_t)sarea->tex_offset + pI830->LinearAddr,
+ sarea->tex_size, DRM_AGP, 0,
+ &sarea->tex_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n");
DRICloseScreen(pScreen);
return FALSE;
}
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Depth Buffer = 0x%08x\n",
- pI830DRI->depthbuffer);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] textures = 0x%08lx\n",
+ sarea->tex_handle);
+
+ return TRUE;
+}
+
+
+void
+I830DRIUnmapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+#if 1
+ if (sarea->front_handle) {
+ drmRmMap(pI830->drmSubFD, sarea->front_handle);
+ sarea->front_handle = 0;
+ }
+#endif
+ if (sarea->back_handle) {
+ drmRmMap(pI830->drmSubFD, sarea->back_handle);
+ sarea->back_handle = 0;
+ }
+ if (sarea->depth_handle) {
+ drmRmMap(pI830->drmSubFD, sarea->depth_handle);
+ sarea->depth_handle = 0;
+ }
+ if (sarea->tex_handle) {
+ drmRmMap(pI830->drmSubFD, sarea->tex_handle);
+ sarea->tex_handle = 0;
+ }
+}
+static void
+I830InitTextureHeap(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ /* Start up the simple memory manager for agp space */
+ drmI830MemInitHeap drmHeap;
+ drmHeap.region = I830_MEM_REGION_AGP;
+ drmHeap.start = 0;
+ drmHeap.size = sarea->tex_size;
+
+ if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT_HEAP,
+ &drmHeap, sizeof(drmHeap))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] Failed to initialized agp heap manager\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] Initialized kernel agp heap manager, %d\n",
+ sarea->tex_size);
+
+ I830SetParam(pScrn, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY,
+ sarea->log_tex_granularity);
+ }
+}
+
+Bool
+I830DRIDoMappings(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
+ I830DRIPtr pI830DRI = pDRIInfo->devPrivate;
+ drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
+
+ DPRINTF(PFX, "I830DRIDoMappings\n");
+ pI830DRI->regsSize = I830_REG_SIZE;
+ if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr,
+ pI830DRI->regsSize, DRM_REGISTERS, 0, &pI830DRI->regs) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n");
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08lx\n",
+ pI830DRI->regs);
if (drmAddMap(pI830->drmSubFD,
(drm_handle_t)pI830->LpRing->mem.Start + pI830->LinearAddr,
@@ -662,25 +756,29 @@ I830DRIDoMappings(ScreenPtr pScreen)
DRICloseScreen(pScreen);
return FALSE;
}
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] ring buffer = 0x%08x\n",
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] ring buffer = 0x%08lx\n",
pI830->ring_map);
- pI830DRI->textureSize = pI830->TexMem.Size;
- pI830DRI->logTextureGranularity = pI830->TexGranularity;
-
- if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)pI830->TexMem.Start + pI830->LinearAddr,
- pI830->TexMem.Size, DRM_AGP, 0,
- &pI830DRI->textures) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] drmAddMap(textures) failed. Disabling DRI\n");
+ if (!I830InitDma(pScrn)) {
DRICloseScreen(pScreen);
return FALSE;
}
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] textures = 0x%08x\n",
- pI830DRI->textures);
- if (!I830InitDma(pScrn)) {
+ /* init to zero to be safe */
+ sarea->front_handle = 0;
+ sarea->back_handle = 0;
+ sarea->depth_handle = 0;
+ sarea->tex_handle = 0;
+
+ /* Need to initialize pScreen now to let RandR know. */
+ pScrn->pScreen->width = pScrn->virtualX;
+ pScrn->pScreen->height = pScrn->virtualY;
+
+ /* this will map the screen regions */
+ if (!I830UpdateDRIBuffers(pScrn, sarea)) {
+ /* screen mappings probably failed */
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] drmAddMap(screen mappings) failed. Disabling DRI\n");
DRICloseScreen(pScreen);
return FALSE;
}
@@ -713,29 +811,6 @@ I830DRIDoMappings(ScreenPtr pScreen)
pI830DRI->irq);
}
- /* Start up the simple memory manager for agp space */
- {
- drmI830MemInitHeap drmHeap;
- drmHeap.region = I830_MEM_REGION_AGP;
- drmHeap.start = 0;
- drmHeap.size = pI830DRI->textureSize;
-
- if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT_HEAP,
- &drmHeap, sizeof(drmHeap))) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] Failed to initialized agp heap manager\n");
- } else {
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] Initialized kernel agp heap manager, %d\n",
- pI830DRI->textureSize);
-
- I830SetParam(pScrn, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY,
- pI830->TexGranularity);
- }
- }
-
-
-
pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
pI830DRI->deviceID = pI830->PciInfo->chipType;
pI830DRI->width = pScrn->virtualX;
@@ -748,13 +823,6 @@ I830DRIDoMappings(ScreenPtr pScreen)
pI830DRI->bitsPerPixel = pScrn->bitsPerPixel;
- pI830DRI->textureOffset = pI830->TexMem.Start;
-
- pI830DRI->backOffset = pI830->BackBuffer.Start;
- pI830DRI->depthOffset = pI830->DepthBuffer.Start;
-
- pI830DRI->backPitch = pI830->backPitch;
- pI830DRI->depthPitch = pI830->backPitch;
pI830DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
if (!(I830InitVisualConfigs(pScreen))) {
@@ -854,23 +922,23 @@ I830DestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
Bool
I830DRIFinishScreenInit(ScreenPtr pScreen)
{
- drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX, "I830DRIFinishScreenInit\n");
- memset(sPriv, 0, sizeof(sPriv));
-
/* Have shadow run only while there is 3d active.
*/
+#if 0
if (pI830->allowPageFlip && pI830->drmMinor >= 1) {
shadowSetup(pScreen);
shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0);
}
else
+#endif
pI830->allowPageFlip = 0;
+
return DRIFinishScreenInit(pScreen);
}
@@ -965,8 +1033,13 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
DDXPointPtr pptTmp, pptNew2;
int xdir, ydir;
+#if 0
int screenwidth = pScrn->virtualX;
int screenheight = pScrn->virtualY;
+#else
+ int screenwidth = pScreen->width;
+ int screenheight = pScreen->height;
+#endif
BoxPtr pbox = REGION_RECTS(prgnSrc);
int nbox = REGION_NUM_RECTS(prgnSrc);
@@ -1152,6 +1225,7 @@ I830EmitInvarientState(ScrnInfoPtr pScrn)
*/
+#if 0
/* This should be done *before* XAA syncs,
* Otherwise will have to sync again???
*/
@@ -1196,7 +1270,7 @@ I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
ADVANCE_LP_RING();
}
}
-
+#endif
static void
I830EnablePageFlip(ScreenPtr pScreen)
@@ -1261,7 +1335,6 @@ I830DRITransitionMultiToSingle3d(ScreenPtr pScreen)
I830EnablePageFlip(pScreen);
}
-
static void
I830DRITransitionTo3d(ScreenPtr pScreen)
{
@@ -1294,3 +1367,107 @@ I830DRITransitionTo2d(ScreenPtr pScreen)
}
+/**
+ * Update the SAREA fields with the most recent values.
+ * This gets called after the screen orientation/rotation changes.
+ */
+Bool
+I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ Bool success;
+
+ I830DRIUnmapScreenRegions(pScrn, sarea);
+
+ if (pI830->rotation == RR_Rotate_0) {
+ sarea->front_offset = pI830->FrontBuffer.Start;
+ /* Don't use FrontBuffer.Size here as it includes the pixmap cache area
+ * Instead, calculate the entire framebuffer.
+ */
+ sarea->front_size = pI830->displayWidth * pScrn->virtualY * pI830->cpp;
+ } else {
+ /* Need to deal with rotated2 once we have dual head DRI */
+ sarea->front_offset = pI830->RotatedMem.Start;
+ sarea->front_size = pI830->RotatedMem.Size;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] init sarea width,height = %d x %d (pitch %d)\n",
+ pScreen->width, pScreen->height,pScrn->displayWidth);
+
+ sarea->width = pScreen->width;
+ sarea->height = pScreen->height;
+ sarea->back_offset = pI830->BackBuffer.Start;
+ sarea->back_size = pI830->BackBuffer.Size;
+ sarea->depth_offset = pI830->DepthBuffer.Start;
+ sarea->depth_size = pI830->DepthBuffer.Size;
+ sarea->tex_offset = pI830->TexMem.Start;
+ sarea->tex_size = pI830->TexMem.Size;
+ sarea->log_tex_granularity = pI830->TexGranularity;
+ sarea->pitch = pScrn->displayWidth;
+ sarea->virtualX = pScrn->virtualX;
+ sarea->virtualY = pScrn->virtualY;
+
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ sarea->rotation = 0;
+ break;
+ case RR_Rotate_90:
+ sarea->rotation = 90;
+ break;
+ case RR_Rotate_180:
+ sarea->rotation = 180;
+ break;
+ case RR_Rotate_270:
+ sarea->rotation = 270;
+ break;
+ default:
+ sarea->rotation = 0;
+ }
+ if (pI830->rotation == RR_Rotate_0) {
+ sarea->rotated_offset = -1;
+ sarea->rotated_size = 0;
+ }
+ else {
+ sarea->rotated_offset = pI830->FrontBuffer.Start;
+ sarea->rotated_size = pI830->FrontBuffer.Size;
+ }
+
+ /* This is the original pitch */
+ sarea->rotated_pitch = pI830->displayWidth;
+
+ success = I830DRIMapScreenRegions(pScrn, sarea);
+
+ I830InitTextureHeap(pScrn, sarea);
+
+ return success;
+}
+
+Bool
+I830DRILock(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (pI830->directRenderingEnabled && !pI830->LockHeld) {
+ DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
+ pI830->LockHeld = 1;
+ I830RefreshRing(pScrn);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+
+void
+I830DRIUnlock(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (pI830->directRenderingEnabled && pI830->LockHeld) {
+ DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
+ pI830->LockHeld = 0;
+ }
+}
diff --git a/src/i830_dri.h b/src/i830_dri.h
index 5ac99e5e..b1cb5887 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -9,8 +9,8 @@
#define I830_MAX_DRAWABLES 256
#define I830_MAJOR_VERSION 1
-#define I830_MINOR_VERSION 4
-#define I830_PATCHLEVEL 1
+#define I830_MINOR_VERSION 5
+#define I830_PATCHLEVEL 0
#define I830_REG_SIZE 0x80000
@@ -24,6 +24,9 @@ typedef struct _I830DRIRec {
drmSize depthbufferSize;
drm_handle_t depthbuffer;
+ drmSize rotatedSize;
+ drm_handle_t rotatedbuffer;
+
drm_handle_t textures;
int textureSize;
@@ -46,6 +49,9 @@ typedef struct _I830DRIRec {
int depthOffset;
int depthPitch;
+ int rotatedOffset;
+ int rotatedPitch;
+
int logTextureGranularity;
int textureOffset;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index b281affd..29606c42 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -144,8 +144,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* - Fix Xvideo with high-res LFP's
* - Add ARGB HW cursor support
*
- * 30/2005 Alan Hourihane
+ * 05/2005 Alan Hourihane
* - Add Intel(R) 945G support.
+ *
+ * 09/2005 Alan Hourihane
+ * - Add Intel(R) 945GM support.
+ *
*/
#ifdef HAVE_CONFIG_H
@@ -168,14 +172,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "mipointer.h"
#include "micmap.h"
#include "shadowfb.h"
-
+#include <X11/extensions/randr.h>
#include "fb.h"
#include "miscstruct.h"
#include "xf86xv.h"
#include <X11/extensions/Xv.h>
#include "vbe.h"
#include "vbeModes.h"
-
+#include "shadow.h"
#include "i830.h"
#ifdef XF86DRI
@@ -196,6 +200,7 @@ static SymTabRec I830BIOSChipsets[] = {
{PCI_CHIP_E7221_G, "E7221 (i915)"},
{PCI_CHIP_I915_GM, "915GM"},
{PCI_CHIP_I945_G, "945G"},
+ {PCI_CHIP_I945_GM, "945GM"},
{-1, NULL}
};
@@ -208,6 +213,7 @@ static PciChipsets I830BIOSPciChipsets[] = {
{PCI_CHIP_E7221_G, PCI_CHIP_E7221_G, RES_SHARED_VGA},
{PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, RES_SHARED_VGA},
{PCI_CHIP_I945_G, PCI_CHIP_I945_G, RES_SHARED_VGA},
+ {PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED}
};
@@ -234,8 +240,8 @@ typedef enum {
OPTION_CLONE_REFRESH,
OPTION_CHECKDEVICES,
OPTION_FIXEDPIPE,
- OPTION_SHADOW_FB,
- OPTION_ROTATE
+ OPTION_ROTATE,
+ OPTION_LINEARALLOC
} I830Opts;
static OptionInfoRec I830BIOSOptions[] = {
@@ -255,8 +261,8 @@ static OptionInfoRec I830BIOSOptions[] = {
{OPTION_CLONE_REFRESH,"CloneRefresh",OPTV_INTEGER, {0}, FALSE},
{OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN, {0}, FALSE},
{OPTION_FIXEDPIPE, "FixedPipe", OPTV_ANYSTR, {0}, FALSE},
- {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_LINEARALLOC, "LinearAlloc", OPTV_INTEGER, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
/* *INDENT-ON* */
@@ -271,10 +277,12 @@ static Bool I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode,
VbeCRTCInfoBlock *block);
static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg);
static Bool SetPipeAccess(ScrnInfoPtr pScrn);
-static Bool IsPrimary(ScrnInfoPtr pScrn);
extern int I830EntityIndex;
+/* temporary */
+extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
+
#ifdef I830DEBUG
void
@@ -354,10 +362,12 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn)
} while (mode && mode != pScrn->modes);
}
- if (pI830->vbeInfo)
- VBEFreeVBEInfo(pI830->vbeInfo);
- if (pI830->pVbe)
- vbeFree(pI830->pVbe);
+ if (I830IsPrimary(pScrn)) {
+ if (pI830->vbeInfo)
+ VBEFreeVBEInfo(pI830->vbeInfo);
+ if (pI830->pVbe)
+ vbeFree(pI830->pVbe);
+ }
pVesa = pI830->vesa;
if (pVesa->monitor)
@@ -434,6 +444,93 @@ GetToggleList(ScrnInfoPtr pScrn, int toggle)
}
static int
+GetNextDisplayDeviceList(ScrnInfoPtr pScrn, int toggle)
+{
+ vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
+ int devices = 0;
+ int pipe = 0;
+ int i;
+
+ DPRINTF(PFX, "GetNextDisplayDeviceList\n");
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x5f64;
+ pVbe->pInt10->bx = 0xA00;
+ pVbe->pInt10->bx |= toggle;
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+
+ xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
+ if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
+ return 0;
+
+ for (i=0; i<(pVbe->pInt10->cx & 0xff); i++) {
+ CARD32 VODA = (CARD32)((CARD32*)pVbe->memory)[i];
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Next ACPI _DGS [%d] 0x%lx\n",
+ i, VODA);
+
+ /* Check if it's a custom Video Output Device Attribute */
+ if (!(VODA & 0x80000000))
+ continue;
+
+ pipe = (VODA & 0x000000F0) >> 4;
+
+ if (pipe != 0 && pipe != 1) {
+ pipe = 0;
+#if 0
+ ErrorF("PIPE %d\n",pipe);
+#endif
+ }
+
+ switch ((VODA & 0x00000F00) >> 8) {
+ case 0x0:
+ case 0x1: /* CRT */
+ devices |= PIPE_CRT << (pipe == 1 ? 8 : 0);
+ break;
+ case 0x2: /* TV/HDTV */
+ devices |= PIPE_TV << (pipe == 1 ? 8 : 0);
+ break;
+ case 0x3: /* DFP */
+ devices |= PIPE_DFP << (pipe == 1 ? 8 : 0);
+ break;
+ case 0x4: /* LFP */
+ devices |= PIPE_LFP << (pipe == 1 ? 8 : 0);
+ break;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle devices 0x%x\n", devices);
+
+ return devices;
+}
+
+static int
+GetAttachableDisplayDeviceList(ScrnInfoPtr pScrn)
+{
+ vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
+ int i;
+
+ DPRINTF(PFX, "GetAttachableDisplayDeviceList\n");
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x5f64;
+ pVbe->pInt10->bx = 0x900;
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+
+ xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
+ if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
+ return 0;
+
+ for (i=0; i<(pVbe->pInt10->cx & 0xff); i++)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Attachable device 0x%lx.\n", ((CARD32*)pVbe->memory)[i]);
+
+ return pVbe->pInt10->cx & 0xffff;
+}
+
+static int
BitToRefresh(int bits)
{
int i;
@@ -624,6 +721,7 @@ SetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh)
return 0;
}
+#if 0
static Bool
SetPowerStatus(ScrnInfoPtr pScrn, int mode)
{
@@ -640,6 +738,7 @@ SetPowerStatus(ScrnInfoPtr pScrn, int mode)
return FALSE;
}
+#endif
static Bool
GetModeSupport(ScrnInfoPtr pScrn, int modePipeA, int modePipeB,
@@ -677,6 +776,7 @@ GetModeSupport(ScrnInfoPtr pScrn, int modePipeA, int modePipeB,
return FALSE;
}
+#if 0
static int
GetLFPCompMode(ScrnInfoPtr pScrn)
{
@@ -695,7 +795,6 @@ GetLFPCompMode(ScrnInfoPtr pScrn)
return -1;
}
-#if 0
static Bool
SetLFPCompMode(ScrnInfoPtr pScrn, int compMode)
{
@@ -882,7 +981,7 @@ SetDisplayDevices(ScrnInfoPtr pScrn, int devices)
setmode = FALSE;
if (pI830->closing)
setmode = FALSE;
-
+
if (setmode) {
VBEGetVBEMode(pVbe, &getmode1);
I830Set640x480(pScrn);
@@ -1323,7 +1422,7 @@ I830DetectMemory(ScrnInfoPtr pScrn)
* The GTT varying according the the FbMapSize and the popup is 4KB */
range = (pI830->FbMapSize / (1024*1024)) + 4;
- if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
+ if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I855_GMCH_GMS_STOLEN_1M:
memsize = MB(1) - KB(range);
@@ -1341,11 +1440,11 @@ I830DetectMemory(ScrnInfoPtr pScrn)
memsize = MB(32) - KB(range);
break;
case I915G_GMCH_GMS_STOLEN_48M:
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
+ if (IS_I9XX(pI830))
memsize = MB(48) - KB(range);
break;
case I915G_GMCH_GMS_STOLEN_64M:
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
+ if (IS_I9XX(pI830))
memsize = MB(64) - KB(range);
break;
}
@@ -1414,7 +1513,7 @@ I830MapMem(ScrnInfoPtr pScrn)
if (!pI830->FbBase)
return FALSE;
- if (IsPrimary(pScrn))
+ if (I830IsPrimary(pScrn))
pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem.Start;
return TRUE;
@@ -1513,6 +1612,9 @@ SaveBIOSMemSize(ScrnInfoPtr pScrn)
DPRINTF(PFX, "SaveBIOSMemSize\n");
+ if (!I830IsPrimary(pScrn))
+ return FALSE;
+
pI830->useSWF1 = FALSE;
#if HAVE_GET_PUT_BIOSMEMSIZE
@@ -1572,6 +1674,9 @@ TweakMemorySize(ScrnInfoPtr pScrn, CARD32 newsize, Bool preinit)
PCITAG tag =pciTag(0,0,0);
+ if (!I830IsPrimary(pScrn))
+ return 0;
+
if(!pI830->PciInfo
|| !(IS_845G(pI830) || IS_I85X(pI830) || IS_I865G(pI830)))
return 0;
@@ -1618,10 +1723,16 @@ TweakMemorySize(ScrnInfoPtr pScrn, CARD32 newsize, Bool preinit)
if (preinit) {
/* reinitialize VBE for new size */
- VBEFreeVBEInfo(pI830->vbeInfo);
- vbeFree(pI830->pVbe);
- pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
- pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
+ if (I830IsPrimary(pScrn)) {
+ VBEFreeVBEInfo(pI830->vbeInfo);
+ vbeFree(pI830->pVbe);
+ pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
+ pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pI830->pVbe = pI8301->pVbe;
+ pI830->vbeInfo = pI8301->vbeInfo;
+ }
/* verify that change was successful */
if (pI830->vbeInfo->TotalMemory != (newsize >> 16)){
@@ -1648,8 +1759,11 @@ RestoreBIOSMemSize(ScrnInfoPtr pScrn)
DPRINTF(PFX, "RestoreBIOSMemSize\n");
+ if (!I830IsPrimary(pScrn))
+ return;
+
if (TweakMemorySize(pScrn, pI830->saveBIOSMemSize,FALSE))
- return;
+ return;
if (!pI830->overrideBIOSMemSize)
return;
@@ -1712,6 +1826,8 @@ SetBIOSMemSize(ScrnInfoPtr pScrn, int newSize)
}
}
+static CARD32 val8[256];
+
static void
I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
LOCO * colors, VisualPtr pVisual)
@@ -1786,6 +1902,19 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
}
break;
default:
+#if 1
+ /* Dual head 8bpp modes seem to squish the primary's cmap - reload */
+ if (I830IsPrimary(pScrn) && xf86IsEntityShared(pScrn->entityList[0]) &&
+ pScrn->depth == 8) {
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ r = colors[index].red;
+ g = colors[index].green;
+ b = colors[index].blue;
+ val8[index] = (r << 16) | (g << 8) | b;
+ }
+ }
+#endif
for(i = 0; i < numColors; i++) {
index = indices[i];
r = colors[index].red;
@@ -1793,6 +1922,16 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
b = colors[index].blue;
val = (r << 16) | (g << 8) | b;
OUTREG(palreg + index * 4, val);
+#if 1
+ /* Dual head 8bpp modes seem to squish the primary's cmap - reload */
+ if (!I830IsPrimary(pScrn) && xf86IsEntityShared(pScrn->entityList[0]) &&
+ pScrn->depth == 8) {
+ if (palreg == PALETTE_A)
+ OUTREG(PALETTE_B + index * 4, val8[index]);
+ else
+ OUTREG(PALETTE_A + index * 4, val8[index]);
+ }
+#endif
}
break;
}
@@ -1868,30 +2007,32 @@ PreInitCleanup(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
- if (IsPrimary(pScrn))
+ if (I830IsPrimary(pScrn)) {
+ SetPipeAccess(pScrn);
+
pI830->entityPrivate->pScrn_1 = NULL;
- if (IsPrimary(pScrn) && pI830->LpRing) {
- xfree(pI830->LpRing);
+ if (pI830->LpRing)
+ xfree(pI830->LpRing);
pI830->LpRing = NULL;
- }
- if (IsPrimary(pScrn) && pI830->CursorMem) {
- xfree(pI830->CursorMem);
+ if (pI830->CursorMem)
+ xfree(pI830->CursorMem);
pI830->CursorMem = NULL;
- }
- if (IsPrimary(pScrn) && pI830->CursorMemARGB) {
- xfree(pI830->CursorMemARGB);
+ if (pI830->CursorMemARGB)
+ xfree(pI830->CursorMemARGB);
pI830->CursorMemARGB = NULL;
- }
- if (IsPrimary(pScrn) && pI830->OverlayMem) {
- xfree(pI830->OverlayMem);
+ if (pI830->OverlayMem)
+ xfree(pI830->OverlayMem);
pI830->OverlayMem = NULL;
- }
- if (IsPrimary(pScrn) && pI830->overlayOn) {
- xfree(pI830->overlayOn);
+ if (pI830->overlayOn)
+ xfree(pI830->overlayOn);
pI830->overlayOn = NULL;
+ if (pI830->used3D)
+ xfree(pI830->used3D);
+ pI830->used3D = NULL;
+ } else {
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->pScrn_2 = NULL;
}
- if (!IsPrimary(pScrn) && pI830->entityPrivate)
- pI830->entityPrivate->pScrn_2 = NULL;
RestoreBIOSMemSize(pScrn);
if (pI830->swfSaved) {
OUTREG(SWF0, pI830->saveSWF0);
@@ -1902,8 +2043,8 @@ PreInitCleanup(ScrnInfoPtr pScrn)
I830BIOSFreeRec(pScrn);
}
-static Bool
-IsPrimary(ScrnInfoPtr pScrn)
+Bool
+I830IsPrimary(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
@@ -1920,7 +2061,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
{
vgaHWPtr hwp;
I830Ptr pI830;
- MessageType from;
+ MessageType from = X_PROBED;
rgb defaultWeight = { 0, 0, 0 };
EntityInfoPtr pEnt;
I830EntPtr pI830Ent = NULL;
@@ -1974,6 +2115,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->SaveGeneration = -1;
pI830->pEnt = pEnt;
+ pI830->displayWidth = 640; /* default it */
+
if (pI830->pEnt->location.type != BUS_PCI)
return FALSE;
@@ -1994,6 +2137,30 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ if (xf86IsPrimInitDone(pScrn->entityList[0])) {
+ pI830->init = 1;
+
+ if (!pI830Ent->pScrn_1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to setup second head due to primary head failure.\n");
+ return FALSE;
+ }
+ } else {
+ xf86SetPrimInitDone(pScrn->entityList[0]);
+ pI830->init = 0;
+ }
+ }
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ if (!I830IsPrimary(pScrn)) {
+ pI830Ent->pScrn_2 = pScrn;
+ } else {
+ pI830Ent->pScrn_1 = pScrn;
+ pI830Ent->pScrn_2 = NULL;
+ }
+ }
+
pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
pScrn->monitor = pScrn->confScreen->monitor;
pScrn->progClock = TRUE;
@@ -2039,9 +2206,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
I830SetPIOAccess(pI830);
/* Initialize VBE record */
- if ((pI830->pVbe = VBEInit(NULL, pI830->pEnt->index)) == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VBE initialization failed.\n");
- return FALSE;
+ if (I830IsPrimary(pScrn)) {
+ if ((pI830->pVbe = VBEInit(NULL, pI830->pEnt->index)) == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VBE initialization failed.\n");
+ return FALSE;
+ }
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pI830->pVbe = pI8301->pVbe;
}
switch (pI830->PciInfo->chipType) {
@@ -2090,6 +2262,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_I945_G:
chipname = "945G";
break;
+ case PCI_CHIP_I945_GM:
+ chipname = "945GM";
+ break;
default:
chipname = "unknown chipset";
break;
@@ -2097,7 +2272,12 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Integrated Graphics Chipset: Intel(R) %s\n", chipname);
- pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
+ if (I830IsPrimary(pScrn)) {
+ pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pI830->vbeInfo = pI8301->vbeInfo;
+ }
/* Set the Chipset and ChipRev, allowing config file entries to override. */
if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) {
@@ -2127,8 +2307,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->LinearAddr = pI830->pEnt->device->MemBase;
from = X_CONFIG;
} else {
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
- pI830->LinearAddr = pI830->PciInfo->memBase[2] & 0xF0000000;
+ if (IS_I9XX(pI830)) {
+ pI830->LinearAddr = pI830->PciInfo->memBase[2] & 0xFF000000;
from = X_PROBED;
} else if (pI830->PciInfo->memBase[1] != 0) {
/* XXX Check mask. */
@@ -2149,7 +2329,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->MMIOAddr = pI830->pEnt->device->IOBase;
from = X_CONFIG;
} else {
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
+ if (IS_I9XX(pI830)) {
pI830->MMIOAddr = pI830->PciInfo->memBase[0] & 0xFFF80000;
from = X_PROBED;
} else if (pI830->PciInfo->memBase[1]) {
@@ -2194,7 +2374,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */
}
} else {
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
+ if (IS_I9XX(pI830)) {
if (pI830->PciInfo->memBase[2] & 0x08000000)
pI830->FbMapSize = 0x8000000; /* 128MB aperture */
else
@@ -2207,27 +2387,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->FbMapSize = 0x8000000;
}
-
- if (xf86IsEntityShared(pScrn->entityList[0])) {
- if (xf86IsPrimInitDone(pScrn->entityList[0])) {
- pI830->init = 1;
-
- if (!pI830Ent->pScrn_1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to setup second head due to primary head failure.\n");
- return FALSE;
- }
-
- } else {
- xf86SetPrimInitDone(pScrn->entityList[0]);
- pI830->init = 0;
- }
- }
-
if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
pI830->availablePipes = 1;
else
- if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830))
+ if (IS_MOBILE(pI830) || IS_I9XX(pI830))
pI830->availablePipes = 2;
else
pI830->availablePipes = 1;
@@ -2251,7 +2414,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
/* Find the maximum amount of agpgart memory available. */
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
mem = I830CheckAvailableMemory(pScrn);
pI830->StolenOnly = FALSE;
} else {
@@ -2302,9 +2465,16 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
+ pI830->LinearAlloc = 0;
+ if (xf86GetOptValInteger(pI830->Options, OPTION_LINEARALLOC,
+ &(pI830->LinearAlloc))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %dKbytes of memory\n",
+ pI830->LinearAlloc);
+ }
+
pI830->fixedPipe = -1;
if ((s = xf86GetOptValString(pI830->Options, OPTION_FIXEDPIPE)) &&
- IsPrimary(pScrn)) {
+ I830IsPrimary(pScrn)) {
if (strstr(s, "A") || strstr(s, "a") || strstr(s, "0"))
pI830->fixedPipe = 0;
@@ -2317,7 +2487,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->specifiedMonitor = FALSE;
if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) &&
- IsPrimary(pScrn)) {
+ I830IsPrimary(pScrn)) {
char *Mon1;
char *Mon2;
char *sub;
@@ -2429,7 +2599,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
- if ((pI830->entityPrivate && IsPrimary(pScrn)) || pI830->Clone) {
+ if ((pI830->entityPrivate && I830IsPrimary(pScrn)) || pI830->Clone) {
if ((!xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "You must have a MonitorLayout "
"defined for use in a DualHead or Clone setup.\n");
@@ -2443,37 +2613,17 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
PreInitCleanup(pScrn);
return FALSE;
}
- }
-
- xf86GetOptValBool(pI830->Options, OPTION_SHADOW_FB, &pI830->shadowFB);
- if (pI830->shadowFB) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: shadow FB enabled\n");
- }
-
- if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) {
- if(!xf86NameCmp(s, "CW")) {
- /* accel is disabled below for shadowFB */
- pI830->shadowFB = TRUE;
- pI830->rotate = 1;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Rotating screen clockwise - acceleration disabled\n");
- } else if(!xf86NameCmp(s, "CCW")) {
- pI830->shadowFB = TRUE;
- pI830->rotate = -1;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen"
- "counter clockwise - acceleration disabled\n");
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
- "value for Option \"Rotate\"\n", s);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Valid options are \"CW\" or \"CCW\"\n");
- }
- }
+ }
- if (pI830->shadowFB && !pI830->noAccel) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "HW acceleration not supported with \"shadowFB\".\n");
- pI830->noAccel = TRUE;
+ pI830->rotation = RR_Rotate_0;
+ if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) {
+ pI830->InitialRotation = 0;
+ if(!xf86NameCmp(s, "CW") || !xf86NameCmp(s, "270"))
+ pI830->InitialRotation = 270;
+ if(!xf86NameCmp(s, "CCW") || !xf86NameCmp(s, "90"))
+ pI830->InitialRotation = 90;
+ if(!xf86NameCmp(s, "180"))
+ pI830->InitialRotation = 180;
}
/*
@@ -2486,7 +2636,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->checkDevices = FALSE;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
} else
- if (pI830->entityPrivate && !IsPrimary(pScrn) &&
+ if (pI830->entityPrivate && !I830IsPrimary(pScrn) &&
!I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) {
/* If checklid is off, on the primary head, then
* turn it off on the secondary*/
@@ -2525,7 +2675,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pScrn->videoRam = I830_DEFAULT_VIDEOMEM_2D;
if (xf86IsEntityShared(pScrn->entityList[0])) {
- if (IsPrimary(pScrn))
+ if (I830IsPrimary(pScrn))
pScrn->videoRam *= 2;
else
pScrn->videoRam = I830_MAXIMUM_VBIOS_MEM;
@@ -2538,6 +2688,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pScrn->videoRam = pI830->pEnt->device->videoRam;
}
+ /* Make sure it's on a page boundary */
+ if (pScrn->videoRam & (GTT_PAGE_SIZE - 1)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "VideoRAM reduced to %d kByte "
+ "(page aligned - was %d)\n", pScrn->videoRam & ~(GTT_PAGE_SIZE - 1), pScrn->videoRam);
+ pScrn->videoRam &= ~(GTT_PAGE_SIZE - 1);
+ }
+
DPRINTF(PFX,
"Available memory: %dk\n"
"Requested memory: %dk\n", mem, pScrn->videoRam);
@@ -2597,10 +2755,16 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->overrideBIOSMemSize = TRUE;
SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
- VBEFreeVBEInfo(pI830->vbeInfo);
- vbeFree(pI830->pVbe);
- pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
- pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
+ if (I830IsPrimary(pScrn)) {
+ VBEFreeVBEInfo(pI830->vbeInfo);
+ vbeFree(pI830->pVbe);
+ pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
+ pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pI830->pVbe = pI8301->pVbe;
+ pI830->vbeInfo = pI8301->vbeInfo;
+ }
pI830->BIOSMemorySize = KB(pI830->vbeInfo->TotalMemory * 64);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -2698,21 +2862,15 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS Build: %d\n",pI830->bios_version);
- /* Great..
- * Intel changed the BIOS version codes and started at 1200.
- * We know that bios codes for 830M started around 2400.
- * So we test those conditions to make this judgement. Ugh.
- */
- if (pI830->availablePipes == 2 && pI830->bios_version < 2000)
+ if (IS_I9XX(pI830))
pI830->newPipeSwitch = TRUE;
- else if (pI830->availablePipes == 2 && pI830->bios_version >= 3062)
+ else
+ if (pI830->availablePipes == 2 && pI830->bios_version >= 3062) {
/* BIOS build 3062 changed the pipe switching functionality */
pI830->newPipeSwitch = TRUE;
- else
- pI830->newPipeSwitch = FALSE;
-
- if (pI830->newPipeSwitch)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using new Pipe switch code\n");
+ } else
+ pI830->newPipeSwitch = FALSE;
pI830->devicePresence = FALSE;
from = X_DEFAULT;
@@ -2741,7 +2899,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
/* Save old configuration of detected devices */
pI830->savedDevices = GetDisplayDevices(pScrn);
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
pI830->pipe = pI830->origPipe = GetBIOSPipe(pScrn);
/* Override */
@@ -2783,7 +2941,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
"Primary Pipe has been switched from original pipe (%s to %s)\n",
pI830->origPipe ? "B" : "A", pI830->pipe ? "B" : "A");
} else {
- I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1);
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
pI830->operatingDevices = pI8301->operatingDevices;
pI830->pipe = !pI8301->pipe;
pI830->MonType1 = pI8301->MonType1;
@@ -2815,7 +2973,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to switch to monitor configuration (0x%x)\n",
@@ -2832,18 +2990,13 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
PrintDisplayDeviceInfo(pScrn);
if (xf86IsEntityShared(pScrn->entityList[0])) {
- if (!IsPrimary(pScrn)) {
- pI830Ent->pScrn_2 = pScrn;
-
+ if (!I830IsPrimary(pScrn)) {
/* This could be made to work with a little more fiddling */
pI830->directRenderingDisabled = TRUE;
xf86DrvMsg(pScrn->scrnIndex, from, "Secondary head is using Pipe %s\n",
pI830->pipe ? "B" : "A");
} else {
- pI830Ent->pScrn_1 = pScrn;
- pI830Ent->pScrn_2 = NULL;
-
xf86DrvMsg(pScrn->scrnIndex, from, "Primary head is using Pipe %s\n",
pI830->pipe ? "B" : "A");
}
@@ -2853,14 +3006,15 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
/* Alloc our pointers for the primary head */
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
pI830->LpRing = xalloc(sizeof(I830RingBuffer));
pI830->CursorMem = xalloc(sizeof(I830MemRange));
pI830->CursorMemARGB = xalloc(sizeof(I830MemRange));
pI830->OverlayMem = xalloc(sizeof(I830MemRange));
pI830->overlayOn = xalloc(sizeof(Bool));
+ pI830->used3D = xalloc(sizeof(int));
if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB ||
- !pI830->OverlayMem || !pI830->overlayOn) {
+ !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Could not allocate primary data structures.\n");
PreInitCleanup(pScrn);
@@ -2872,7 +3026,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
/* Check if the HW cursor needs physical address. */
- if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830))
+ if (IS_MOBILE(pI830) || IS_I9XX(pI830))
pI830->CursorNeedsPhysical = TRUE;
else
pI830->CursorNeedsPhysical = FALSE;
@@ -2884,8 +3038,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
* XXX If we knew the pre-initialised GTT format for certain, we could
* probably figure out the physical address even in the StolenOnly case.
*/
- if (!IsPrimary(pScrn)) {
- I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1);
+ if (!I830IsPrimary(pScrn)) {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
if (!pI8301->SWCursor) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Using HW Cursor because it's enabled on primary head.\n");
@@ -3157,13 +3311,18 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
* for it, and if there's also enough to allow tiling to be enabled.
*/
#if defined(XF86DRI)
- if (IsPrimary(pScrn) && !pI830->directRenderingDisabled) {
+ if (!I830CheckDRIAvailable(pScrn))
+ pI830->directRenderingDisabled = TRUE;
+
+ if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) {
int savedDisplayWidth = pScrn->displayWidth;
int memNeeded = 0;
- /* Good pitches to allow tiling. Don't care about pitches < 256. */
+ /* Good pitches to allow tiling. Don't care about pitches < 1024. */
static const int pitches[] = {
+/*
128 * 2,
128 * 4,
+*/
128 * 8,
128 * 16,
128 * 32,
@@ -3264,8 +3423,11 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
"Unexpected dry run allocation failure (2).\n");
}
}
- }
+ } else
#endif
+ pI830->disableTiling = TRUE; /* no DRI - so disableTiling */
+
+ pI830->displayWidth = pScrn->displayWidth;
SetPipeAccess(pScrn);
I830PrintModes(pScrn);
@@ -3325,19 +3487,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr);
xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr);
- if (pI830->shadowFB) {
- if (!xf86LoadSubModule(pScrn, "shadowfb")) {
- I830BIOSFreeRec(pScrn);
- vbeFree(pI830->pVbe);
- return FALSE;
- }
- xf86LoaderReqSymLists(I810shadowFBSymbols, NULL);
+#if 0
+ if (I830IsPrimary(pScrn)) {
+ VBEFreeVBEInfo(pI830->vbeInfo);
+ vbeFree(pI830->pVbe);
}
-
- VBEFreeVBEInfo(pI830->vbeInfo);
pI830->vbeInfo = NULL;
- vbeFree(pI830->pVbe);
pI830->pVbe = NULL;
+#endif
/* Use the VBE mode restore workaround by default. */
pI830->vbeRestoreWorkaround = TRUE;
@@ -3357,15 +3514,13 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86LoaderReqSymLists(I810driSymbols, I810drmSymbols, NULL);
}
}
+#endif
- if (!pI830->directRenderingDisabled) {
- if (!xf86LoadSubModule(pScrn, "shadow")) {
- PreInitCleanup(pScrn);
- return FALSE;
- }
- xf86LoaderReqSymLists(I810shadowSymbols, NULL);
+ if (!xf86LoadSubModule(pScrn, "shadow")) {
+ PreInitCleanup(pScrn);
+ return FALSE;
}
-#endif
+ xf86LoaderReqSymLists(I810shadowSymbols, NULL);
pI830->preinit = FALSE;
@@ -3383,7 +3538,7 @@ CheckInheritedState(ScrnInfoPtr pScrn)
int errors = 0, fatal = 0;
unsigned long temp, head, tail;
- if (!IsPrimary(pScrn)) return TRUE;
+ if (!I830IsPrimary(pScrn)) return TRUE;
/* Check first for page table errors */
temp = INREG(PGE_ERR);
@@ -3438,7 +3593,7 @@ ResetState(ScrnInfoPtr pScrn, Bool flush)
DPRINTF(PFX, "ResetState: flush is %s\n", BOOLTOSTRING(flush));
- if (!IsPrimary(pScrn)) return;
+ if (!I830IsPrimary(pScrn)) return;
if (pI830->entityPrivate)
pI830->entityPrivate->RingRunning = 0;
@@ -3460,9 +3615,9 @@ ResetState(ScrnInfoPtr pScrn, Bool flush)
OUTREG(LP_RING + RING_HEAD, 0);
OUTREG(LP_RING + RING_TAIL, 0);
OUTREG(LP_RING + RING_START, 0);
-
+
if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor)
- pI830->CursorInfoRec->HideCursor(pScrn);
+ pI830->CursorInfoRec->HideCursor(pScrn);
}
static void
@@ -3473,7 +3628,7 @@ SetFenceRegs(ScrnInfoPtr pScrn)
DPRINTF(PFX, "SetFenceRegs\n");
- if (!IsPrimary(pScrn)) return;
+ if (!I830IsPrimary(pScrn)) return;
for (i = 0; i < 8; i++) {
OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
@@ -3493,7 +3648,7 @@ SetRingRegs(ScrnInfoPtr pScrn)
if (pI830->noAccel)
return;
- if (!IsPrimary(pScrn)) return;
+ if (!I830IsPrimary(pScrn)) return;
if (pI830->entityPrivate)
pI830->entityPrivate->RingRunning = 1;
@@ -3556,7 +3711,7 @@ SaveHWState(ScrnInfoPtr pScrn)
DPRINTF(PFX, "SaveHWState\n");
- if (IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
+ if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
SetBIOSPipe(pScrn, pI830->origPipe);
else
SetPipeAccess(pScrn);
@@ -3631,7 +3786,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
DPRINTF(PFX, "RestoreHWState\n");
- if (IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
+ if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
SetBIOSPipe(pScrn, pI830->origPipe);
else
SetPipeAccess(pScrn);
@@ -3745,6 +3900,16 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block)
DPRINTF(PFX, "Setting mode 0x%.8x\n", mode);
+#if 0
+ /* Clear the framebuffer (could do this with VBIOS call) */
+ if (I830IsPrimary(pScrn))
+ memset(pI830->FbBase + pI830->FrontBuffer.Start, 0,
+ pScrn->virtualY * pI830->displayWidth * pI830->cpp);
+ else
+ memset(pI830->FbBase + pI830->FrontBuffer2.Start, 0,
+ pScrn->virtualY * pI830->displayWidth * pI830->cpp);
+#endif
+
if (pI830->Clone && pI830->CloneHDisplay && pI830->CloneVDisplay &&
!pI830->preinit && !pI830->closing) {
VbeCRTCInfoBlock newblock;
@@ -3814,7 +3979,6 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block)
"Set refresh rate to %dHz on Clone head.\n",
pI830->CloneRefresh);
}
-
SetPipeAccess(pScrn);
}
@@ -3894,11 +4058,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
mode = data->mode | (1 << 15) | (1 << 14);
#ifdef XF86DRI
- if (pI830->directRenderingEnabled && !pI830->LockHeld) {
- DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
- pI830->LockHeld = 1;
- didLock = TRUE;
- }
+ didLock = I830DRILock(pScrn);
#endif
if (pI830->Clone) {
@@ -3925,13 +4085,13 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
* memory than it's aware of. We check for this later, and set it
* explicitly if necessary.
*/
- if (data->data->XResolution != pScrn->displayWidth) {
+ if (data->data->XResolution != pI830->displayWidth) {
if (pI830->Clone) {
SetBIOSPipe(pScrn, !pI830->pipe);
- VBESetLogicalScanline(pVbe, pScrn->displayWidth);
+ VBESetLogicalScanline(pVbe, pI830->displayWidth);
}
SetPipeAccess(pScrn);
- VBESetLogicalScanline(pVbe, pScrn->displayWidth);
+ VBESetLogicalScanline(pVbe, pI830->displayWidth);
}
if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01) {
@@ -4013,22 +4173,20 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", temp);
}
-
-
if (xf86IsEntityShared(pScrn->entityList[0])) {
/* Clean this up !! */
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
CARD32 stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
CARD32 basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
CARD32 sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
temp = INREG(stridereg);
- if (temp / pI8301->cpp != (CARD32)(pI830->entityPrivate->pScrn_1->displayWidth)) {
+ if (temp / pI8301->cpp != (CARD32)(pI830->displayWidth)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe),
- (int)(temp / pI8301->cpp), pI830->entityPrivate->pScrn_1->displayWidth);
- OUTREG(stridereg, pI830->entityPrivate->pScrn_1->displayWidth * pI8301->cpp);
+ "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe),
+ (int)(temp / pI8301->cpp), pI830->displayWidth);
+ OUTREG(stridereg, pI830->displayWidth * pI8301->cpp);
}
OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
/* Trigger update */
@@ -4042,11 +4200,11 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
temp = INREG(stridereg);
- if (temp / pI8302->cpp != (CARD32)(pI830->entityPrivate->pScrn_2->displayWidth)) {
+ if (temp / pI8302->cpp != (CARD32)(pI8302->displayWidth)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe),
- (int)(temp / pI8302->cpp), pI830->entityPrivate->pScrn_2->displayWidth);
- OUTREG(stridereg, pI830->entityPrivate->pScrn_2->displayWidth * pI8302->cpp);
+ "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe),
+ (int)(temp / pI8302->cpp), pI8302->displayWidth);
+ OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp);
}
OUTREG(sizereg, (pI830->entityPrivate->pScrn_2->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_2->currentMode->VDisplay - 1) << 16));
/* Trigger update */
@@ -4061,11 +4219,11 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
temp = INREG(stridereg);
- if (temp / pI8301->cpp != (CARD32)(pI830->entityPrivate->pScrn_1->displayWidth)) {
+ if (temp / pI8301->cpp != (CARD32)(pI8301->displayWidth)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe),
- (int)(temp / pI8301->cpp), pI830->entityPrivate->pScrn_1->displayWidth);
- OUTREG(stridereg, pI830->entityPrivate->pScrn_1->displayWidth * pI8301->cpp);
+ (int)(temp / pI8301->cpp), pI8301->displayWidth);
+ OUTREG(stridereg, pI8301->displayWidth * pI8301->cpp);
}
OUTREG(sizereg, (pI830->entityPrivate->pScrn_1->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_1->currentMode->VDisplay - 1) << 16));
/* Trigger update */
@@ -4077,11 +4235,11 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
temp = INREG(stridereg);
- if (temp / pI8302->cpp != ((CARD32)pI830->entityPrivate->pScrn_2->displayWidth)) {
+ if (temp / pI8302->cpp != ((CARD32)pI8302->displayWidth)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe),
- (int)(temp / pI8302->cpp), pI830->entityPrivate->pScrn_2->displayWidth);
- OUTREG(stridereg, pI830->entityPrivate->pScrn_2->displayWidth * pI8302->cpp);
+ (int)(temp / pI8302->cpp), pI8302->displayWidth);
+ OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp);
}
OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
/* Trigger update */
@@ -4098,11 +4256,11 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
continue;
temp = INREG(stridereg);
- if (temp / pI830->cpp != (CARD32)pScrn->displayWidth) {
+ if (temp / pI830->cpp != (CARD32)pI830->displayWidth) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(i),
- (int)(temp / pI830->cpp), pScrn->displayWidth);
- OUTREG(stridereg, pScrn->displayWidth * pI830->cpp);
+ (int)(temp / pI830->cpp), pI830->displayWidth);
+ OUTREG(stridereg, pI830->displayWidth * pI830->cpp);
}
OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
/* Trigger update */
@@ -4211,10 +4369,8 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
#endif
#ifdef XF86DRI
- if (pI830->directRenderingEnabled && didLock) {
- DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
- pI830->LockHeld = 0;
- }
+ if (didLock)
+ I830DRIUnlock(pScrn);
#endif
pScrn->vtSema = TRUE;
@@ -4228,7 +4384,7 @@ InitRegisterRec(ScrnInfoPtr pScrn)
I830RegPtr i830Reg = &pI830->ModeReg;
int i;
- if (!IsPrimary(pScrn)) return;
+ if (!I830IsPrimary(pScrn)) return;
for (i = 0; i < 8; i++)
i830Reg->Fence[i] = 0;
@@ -4451,6 +4607,103 @@ I830_dump_registers(ScrnInfoPtr pScrn)
}
#endif
+static void
+I830PointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ I830Ptr pI830 = I830PTR(pScrn);
+ int newX = x, newY = y;
+
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ break;
+ case RR_Rotate_90:
+ newX = y;
+ newY = pScrn->pScreen->width - x - 1;
+ break;
+ case RR_Rotate_180:
+ newX = pScrn->pScreen->width - x - 1;
+ newY = pScrn->pScreen->height - y - 1;
+ break;
+ case RR_Rotate_270:
+ newX = pScrn->pScreen->height - y - 1;
+ newY = x;
+ break;
+ }
+
+ (*pI830->PointerMoved)(index, newX, newY);
+}
+
+static Bool
+I830CreateScreenResources (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ pScreen->CreateScreenResources = pI830->CreateScreenResources;
+ if (!(*pScreen->CreateScreenResources)(pScreen))
+ return FALSE;
+
+ if (pI830->rotation != RR_Rotate_0) {
+ RRScreenSize p;
+ Rotation requestedRotation = pI830->rotation;
+
+ pI830->rotation = RR_Rotate_0;
+
+ /* Just setup enough for an initial rotate */
+ p.width = pScreen->width;
+ p.height = pScreen->height;
+ p.mmWidth = pScreen->mmWidth;
+ p.mmHeight = pScreen->mmHeight;
+
+ pI830->starting = TRUE; /* abuse this for dual head & rotation */
+ I830RandRSetConfig (pScreen, requestedRotation, 0, &p);
+ pI830->starting = FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+I830InitFBManager(
+ ScreenPtr pScreen,
+ BoxPtr FullBox
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RegionRec ScreenRegion;
+ RegionRec FullRegion;
+ BoxRec ScreenBox;
+ Bool ret;
+
+ ScreenBox.x1 = 0;
+ ScreenBox.y1 = 0;
+ ScreenBox.x2 = pScrn->displayWidth;
+ if (pScrn->virtualX > pScrn->virtualY)
+ ScreenBox.y2 = pScrn->virtualX;
+ else
+ ScreenBox.y2 = pScrn->virtualY;
+
+ if((FullBox->x1 > ScreenBox.x1) || (FullBox->y1 > ScreenBox.y1) ||
+ (FullBox->x2 < ScreenBox.x2) || (FullBox->y2 < ScreenBox.y2)) {
+ return FALSE;
+ }
+
+ if (FullBox->y2 < FullBox->y1) return FALSE;
+ if (FullBox->x2 < FullBox->x2) return FALSE;
+
+ REGION_INIT(pScreen, &ScreenRegion, &ScreenBox, 1);
+ REGION_INIT(pScreen, &FullRegion, FullBox, 1);
+
+ REGION_SUBTRACT(pScreen, &FullRegion, &FullRegion, &ScreenRegion);
+
+ ret = xf86InitFBManagerRegion(pScreen, &FullRegion);
+
+ REGION_UNINIT(pScreen, &ScreenRegion);
+ REGION_UNINIT(pScreen, &FullRegion);
+
+ return ret;
+}
+
static Bool
I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
@@ -4458,10 +4711,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
vgaHWPtr hwp;
I830Ptr pI830;
VisualPtr visual;
- I830EntPtr pI830Ent = NULL;
I830Ptr pI8301 = NULL;
- int width, height, displayWidth;
- unsigned char *fbbase;
#ifdef XF86DRI
Bool driDisabled;
#endif
@@ -4470,12 +4720,42 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830 = I830PTR(pScrn);
hwp = VGAHWPTR(pScrn);
- if (xf86IsEntityShared(pScrn->entityList[0])) {
- pI830Ent = pI830->entityPrivate;
- pI8301 = I830PTR(pI830Ent->pScrn_1);
+ pScrn->displayWidth = pI830->displayWidth;
+ switch (pI830->InitialRotation) {
+ case 0:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 0 degrees\n");
+ pI830->rotation = RR_Rotate_0;
+ break;
+ case 90:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 90 degrees\n");
+ pI830->rotation = RR_Rotate_90;
+ break;
+ case 180:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 180 degrees\n");
+ pI830->rotation = RR_Rotate_180;
+ break;
+ case 270:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 270 degrees\n");
+ pI830->rotation = RR_Rotate_270;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad rotation setting - defaulting to 0 degrees\n");
+ pI830->rotation = RR_Rotate_0;
+ break;
+ }
+
+ if (I830IsPrimary(pScrn)) {
+ /* Rotated Buffer */
+ memset(&(pI830->RotatedMem), 0, sizeof(pI830->RotatedMem));
+ pI830->RotatedMem.Key = -1;
+ /* Rotated2 Buffer */
+ memset(&(pI830->RotatedMem2), 0, sizeof(pI830->RotatedMem2));
+ pI830->RotatedMem2.Key = -1;
+ }
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
/* PreInit failed on the second head, so make sure we turn it off */
- if (IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) {
+ if (I830IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) {
if (pI830->pipe == 0) {
pI830->operatingDevices &= 0xFF;
} else {
@@ -4487,7 +4767,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->starting = TRUE;
/* Alloc our pointers for the primary head */
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
if (!pI830->LpRing)
pI830->LpRing = xalloc(sizeof(I830RingBuffer));
if (!pI830->CursorMem)
@@ -4498,8 +4778,10 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->OverlayMem = xalloc(sizeof(I830MemRange));
if (!pI830->overlayOn)
pI830->overlayOn = xalloc(sizeof(Bool));
+ if (!pI830->used3D)
+ pI830->used3D = xalloc(sizeof(int));
if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB ||
- !pI830->OverlayMem || !pI830->overlayOn) {
+ !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Could not allocate primary data structures.\n");
return FALSE;
@@ -4509,31 +4791,42 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->entityPrivate->XvInUse = -1;
}
- if (xf86IsEntityShared(pScrn->entityList[0])) {
- /* Make our second head point to the first heads structures */
- if (!IsPrimary(pScrn)) {
- pI830->LpRing = pI8301->LpRing;
- pI830->CursorMem = pI8301->CursorMem;
- pI830->CursorMemARGB = pI8301->CursorMemARGB;
- pI830->OverlayMem = pI8301->OverlayMem;
- pI830->overlayOn = pI8301->overlayOn;
- }
+ /* Make our second head point to the first heads structures */
+ if (!I830IsPrimary(pScrn)) {
+ pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pI830->LpRing = pI8301->LpRing;
+ pI830->CursorMem = pI8301->CursorMem;
+ pI830->CursorMemARGB = pI8301->CursorMemARGB;
+ pI830->OverlayMem = pI8301->OverlayMem;
+ pI830->overlayOn = pI8301->overlayOn;
+ pI830->used3D = pI8301->used3D;
}
/*
* If we're changing the BIOS's view of the video memory size, do that
* first, then re-initialise the VBE information.
*/
- if (pI830->pVbe)
- vbeFree(pI830->pVbe);
- pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
- if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE))
- SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
+ SetPipeAccess(pScrn);
+ if (I830IsPrimary(pScrn)) {
+ if (pI830->pVbe)
+ vbeFree(pI830->pVbe);
+ pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
+ } else {
+ pI830->pVbe = pI8301->pVbe;
+ }
+ if (I830IsPrimary(pScrn)) {
+ if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE))
+ SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
+ }
if (!pI830->pVbe)
return FALSE;
- if (pI830->vbeInfo)
- VBEFreeVBEInfo(pI830->vbeInfo);
- pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
+ if (I830IsPrimary(pScrn)) {
+ if (pI830->vbeInfo)
+ VBEFreeVBEInfo(pI830->vbeInfo);
+ pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
+ } else {
+ pI830->vbeInfo = pI8301->vbeInfo;
+ }
miClearVisualTypes();
if (!miSetVisualTypes(pScrn->depth,
@@ -4546,7 +4839,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#ifdef I830_XV
pI830->XvEnabled = !pI830->XvDisabled;
if (pI830->XvEnabled) {
- if (!IsPrimary(pScrn)) {
+ if (!I830IsPrimary(pScrn)) {
if (!pI8301->XvEnabled || pI830->noAccel) {
pI830->XvEnabled = FALSE;
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Xv is disabled.\n");
@@ -4562,7 +4855,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->XvEnabled = FALSE;
#endif
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
I830ResetAllocations(pScrn, 0);
if (!I830Allocate2DMemory(pScrn, ALLOC_INITIAL))
@@ -4618,7 +4911,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
*/
if (pI830->directRenderingEnabled) {
- if (pI830->noAccel || pI830->SWCursor || (pI830->StolenOnly && IsPrimary(pScrn))) {
+ if (pI830->noAccel || pI830->SWCursor || (pI830->StolenOnly && I830IsPrimary(pScrn))) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DRI is disabled because it "
"needs HW cursor, 2D accel and AGPGART.\n");
pI830->directRenderingEnabled = FALSE;
@@ -4646,7 +4939,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
* After the 3D allocations have been done, see if there's any free space
* that can be added to the framebuffer allocation.
*/
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
I830Allocate2DMemory(pScrn, 0);
DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n");
@@ -4671,10 +4964,9 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScrn->memPhysBase = (unsigned long)pI830->FbBase;
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
pScrn->fbOffset = pI830->FrontBuffer.Start;
} else {
- I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1);
pScrn->fbOffset = pI8301->FrontBuffer2.Start;
}
@@ -4696,26 +4988,10 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n");
- if (pI830->rotate) {
- height = pScrn->virtualX;
- width = pScrn->virtualY;
- } else {
- width = pScrn->virtualX;
- height = pScrn->virtualY;
- }
- if (pI830->shadowFB) {
- pI830->shadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
- pI830->shadowPtr = xalloc(pI830->shadowPitch * height);
- displayWidth = pI830->shadowPitch / (pScrn->bitsPerPixel >> 3);
- fbbase = pI830->shadowPtr;
- } else {
- pI830->shadowPtr = NULL;
- fbbase = pI830->FbBase;
- displayWidth = pScrn->displayWidth;
- }
- if (!fbScreenInit(pScreen, fbbase + pScrn->fbOffset, width, height,
+ if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset,
+ pScrn->virtualX, pScrn->virtualY,
pScrn->xDpi, pScrn->yDpi,
- displayWidth, pScrn->bitsPerPixel))
+ pScrn->displayWidth, pScrn->bitsPerPixel))
return FALSE;
if (pScrn->bitsPerPixel > 8) {
@@ -4737,22 +5013,24 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
- if (!pI830->shadowFB)
- I830DGAInit(pScreen);
+ I830DGAInit(pScreen);
DPRINTF(PFX,
- "assert( if(!xf86InitFBManager(pScreen, &(pI830->FbMemBox))) )\n");
- if (IsPrimary(pScrn)) {
- if (!xf86InitFBManager(pScreen, &(pI830->FbMemBox))) {
+ "assert( if(!I830InitFBManager(pScreen, &(pI830->FbMemBox))) )\n");
+ if (I830IsPrimary(pScrn)) {
+ if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to init memory manager\n");
- return FALSE;
}
+
+ if (pI830->LinearAlloc && xf86InitFBManagerLinear(pScreen, pI830->LinearMem.Offset / pI830->cpp, pI830->LinearMem.Size / pI830->cpp))
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Using %ld bytes of offscreen memory for linear (offset=0x%lx)\n", pI830->LinearMem.Size, pI830->LinearMem.Offset);
+
} else {
- if (!xf86InitFBManager(pScreen, &(pI8301->FbMemBox2))) {
+ if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to init memory manager\n");
- return FALSE;
}
}
@@ -4776,31 +5054,6 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
} else
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing SW Cursor!\n");
- if (pI830->shadowFB) {
- RefreshAreaFuncPtr refreshArea = I830RefreshArea;
- if (pI830->rotate) {
- if (!pI830->PointerMoved) {
- pI830->PointerMoved = pScrn->PointerMoved;
- pScrn->PointerMoved = I830PointerMoved;
- }
- switch (pScrn->bitsPerPixel) {
- case 8:
- refreshArea = I830RefreshArea8;
- break;
- case 16:
- refreshArea = I830RefreshArea16;
- break;
- case 24:
- refreshArea = I830RefreshArea24;
- break;
- case 32:
- refreshArea = I830RefreshArea32;
- break;
- }
- }
- ShadowFBInit(pScreen, refreshArea);
- }
-
DPRINTF(PFX, "assert( if(!miCreateDefColormap(pScreen)) )\n");
if (!miCreateDefColormap(pScreen))
return FALSE;
@@ -4845,7 +5098,19 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScreen->SaveScreen = I830BIOSSaveScreen;
pI830->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = I830BIOSCloseScreen;
-
+
+ /* Rotation */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
+ xf86DisableRandR(); /* Disable built-in RandR extension */
+
+ shadowSetup(pScreen);
+ /* support all rotations */
+ I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+ pI830->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = I830PointerMoved;
+ pI830->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = I830CreateScreenResources;
+
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@ -4856,6 +5121,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->starting = FALSE;
pI830->closing = FALSE;
pI830->suspended = FALSE;
+
return TRUE;
}
@@ -4865,6 +5131,7 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
ScrnInfoPtr pScrn;
I830Ptr pI830;
vbeInfoPtr pVbe;
+ unsigned long Start;
pScrn = xf86Screens[scrnIndex];
pI830 = I830PTR(pScrn);
@@ -4874,46 +5141,35 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
x, pI830->xoffset, y, pI830->yoffset);
/* Sync the engine before adjust frame */
- if (!pI830->noAccel && pI830->AccelInfoRec)
+ if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
(*pI830->AccelInfoRec->Sync)(pScrn);
+ pI830->AccelInfoRec->NeedToSync = FALSE;
+ }
- /* The i830M just happens to have some problems programming offsets via
- * this VESA BIOS call. Especially in dual head configurations which
- * have high resolutions which cause the DSP{A,B}BASE registers to be
- * programmed incorrectly. Thus, it warrants bypassing the BIOS for i830M
- * and hitting the DSP{A,B}BASE registers directly.
- *
- * We could probably do this for other platforms too, but we don't
- * know what else the Video BIOS may do when calling it. It seems safe
- * though for i830M during testing......
- *
- * Also note, calling the Video BIOS version first and then fixing the
- * registers fail on i830M and eventually cause a lockup of the hardware
- * in my testing.
+ if (I830IsPrimary(pScrn))
+ Start = pI830->FrontBuffer.Start;
+ else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ Start = pI8301->FrontBuffer2.Start;
+ }
+
+ /* Sigh...
+ * It seems that there are quite a few Video BIOS' that get this wrong.
+ * So, we'll bypass the VBE call and hit the hardware directly.
*/
if (pI830->Clone) {
- if (!IS_I830(pI830)) {
- SetBIOSPipe(pScrn, !pI830->pipe);
- VBESetDisplayStart(pVbe, x + pI830->xoffset, y + pI830->yoffset, TRUE);
+ if (!pI830->pipe == 0) {
+ OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
} else {
- if (!pI830->pipe == 0) {
- OUTREG(DSPABASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp));
- } else {
- OUTREG(DSPBBASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp));
- }
+ OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
}
}
- if (!IS_I830(pI830)) {
- SetPipeAccess(pScrn);
- VBESetDisplayStart(pVbe, x + pI830->xoffset, y + pI830->yoffset, TRUE);
+ if (pI830->pipe == 0) {
+ OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
} else {
- if (pI830->pipe == 0) {
- OUTREG(DSPABASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp));
- } else {
- OUTREG(DSPBBASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp));
- }
+ OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
}
}
@@ -4978,7 +5234,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
pI830->CloneVDisplay = 0;
}
- if (!IsPrimary(pScrn)) {
+ if (!I830IsPrimary(pScrn)) {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
if (!pI8301->GttBound) {
return;
@@ -4987,9 +5243,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
#ifdef XF86DRI
if (pI830->directRenderingOpen) {
- DPRINTF(PFX, "calling dri lock\n");
- DRILock(screenInfo.screens[scrnIndex], 0);
- pI830->LockHeld = 1;
+ I830DRILock(pScrn);
drmCtlUninstHandler(pI830->drmSubFD);
}
@@ -5005,7 +5259,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
ResetState(pScrn, TRUE);
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
if (!SetDisplayDevices(pScrn, pI830->savedDevices)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Failed to switch back to original display devices (0x%x)\n",
@@ -5018,13 +5272,13 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
RestoreHWState(pScrn);
RestoreBIOSMemSize(pScrn);
- if (IsPrimary(pScrn))
- I830UnbindGARTMemory(pScrn);
+ if (I830IsPrimary(pScrn))
+ I830UnbindAGPMemory(pScrn);
if (pI830->AccelInfoRec)
pI830->AccelInfoRec->NeedToSync = FALSE;
/* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
if (!SetDisplayDevices(pScrn, pI830->savedDevices)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Failed to switch back to original display devices (0x%x) (2)\n",
@@ -5230,7 +5484,13 @@ I830BIOSEnterVT(int scrnIndex, int flags)
pI830->leaving = FALSE;
- if (IsPrimary(pScrn)) {
+#if 1
+ /* Clear the framebuffer */
+ memset(pI830->FbBase + pScrn->fbOffset, 0,
+ pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
+#endif
+
+ if (I830IsPrimary(pScrn)) {
/*
* This is needed for restoring from ACPI modes (especially S3)
* so that we warmboot the Video BIOS. Some platforms have problems,
@@ -5259,7 +5519,7 @@ I830BIOSEnterVT(int scrnIndex, int flags)
"Re-POSTing via int10 failed, trying to continue.\n");
}
}
-
+
/* Finally, re-setup the display devices */
if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -5269,25 +5529,21 @@ I830BIOSEnterVT(int scrnIndex, int flags)
}
/* Setup for device monitoring status */
- pI830->monitorSwitch = INREG(SWF0) & 0x0000FFFF;
+ pI830->monitorSwitch = pI830->toggleDevices = INREG(SWF0) & 0x0000FFFF;
- if (IsPrimary(pScrn))
- if (!I830BindGARTMemory(pScrn))
+ if (I830IsPrimary(pScrn))
+ if (!I830BindAGPMemory(pScrn))
return FALSE;
CheckInheritedState(pScrn);
- if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE))
- SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
+ if (I830IsPrimary(pScrn)) {
+ if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE))
+ SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
+ }
ResetState(pScrn, FALSE);
SetHWOperatingState(pScrn);
-#if 1
- /* Clear the framebuffer */
- memset(pI830->FbBase + pScrn->fbOffset, 0,
- pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
-#endif
-
/* Detect monitor change and switch to suitable mode */
if (!pI830->starting)
I830DetectMonitorChange(pScrn);
@@ -5319,7 +5575,7 @@ I830BIOSEnterVT(int scrnIndex, int flags)
DO_RING_IDLE();
DPRINTF(PFX, "calling dri unlock\n");
- DRIUnlock(screenInfo.screens[scrnIndex]);
+ I830DRIUnlock(pScrn);
}
pI830->LockHeld = 0;
}
@@ -5328,6 +5584,11 @@ I830BIOSEnterVT(int scrnIndex, int flags)
if (pI830->checkDevices)
pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn);
+ pI830->currentMode = pScrn->currentMode;
+
+ /* Force invarient state when rotated to be emitted */
+ *pI830->used3D = 1<<31;
+
return TRUE;
}
@@ -5337,35 +5598,64 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
- int ret = TRUE;
+ Bool ret = TRUE;
+ PixmapPtr pspix = (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen);
DPRINTF(PFX, "I830BIOSSwitchMode: mode == %p\n", mode);
- /* Sync the engine before mode switch */
- if (!pI830->noAccel && pI830->AccelInfoRec)
- (*pI830->AccelInfoRec->Sync)(pScrn);
-
-#ifndef BINDUNBIND
-#define BINDUNBIND 0
-#endif
-#if BINDUNBIND
- if (IsPrimary(pScrn))
- I830UnbindGARTMemory(pScrn);
-#endif
#ifdef I830_XV
/* Give the video overlay code a chance to see the new mode. */
I830VideoSwitchModeBefore(pScrn, mode);
#endif
- if (!I830VESASetMode(pScrn, mode))
- ret = FALSE;
+
+ /* Sync the engine before mode switch */
+ if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+ (*pI830->AccelInfoRec->Sync)(pScrn);
+ pI830->AccelInfoRec->NeedToSync = FALSE;
+ }
+
+ /* Check if our currentmode is about to change. We do this so if we
+ * are rotating, we don't need to call the mode setup again.
+ */
+ if (pI830->currentMode != mode) {
+ if (!I830VESASetMode(pScrn, mode))
+ ret = FALSE;
+ }
+
+ /* Kludge to detect Rotate or Vidmode switch. Not very elegant, but
+ * workable given the implementation currently. We only need to call
+ * the rotation function when we know that the framebuffer has been
+ * disabled by the EnableDisableFBAccess() function.
+ *
+ * The extra WindowTable check detects a rotation at startup.
+ */
+ if ( (!WindowTable[pScrn->scrnIndex] || pspix->devPrivate.ptr == NULL) &&
+ !pI830->DGAactive ) {
+ if (!I830Rotate(pScrn, mode))
+ ret = FALSE;
+ }
+
+ /* Either the original setmode or rotation failed, so restore the previous
+ * video mode here, as we'll have already re-instated the original rotation.
+ */
+ if (!ret) {
+ if (!I830VESASetMode(pScrn, pI830->currentMode)) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Failed to restore previous mode (SwitchMode)\n");
+ }
+
#ifdef I830_XV
- /* Give the video overlay code a chance to see the new mode. */
- I830VideoSwitchModeAfter(pScrn, mode);
+ /* Give the video overlay code a chance to see the new mode. */
+ I830VideoSwitchModeAfter(pScrn, pI830->currentMode);
#endif
-#if BINDUNBIND
- if (IsPrimary(pScrn))
- I830BindGARTMemory(pScrn);
+ } else {
+ pI830->currentMode = mode;
+
+#ifdef I830_XV
+ /* Give the video overlay code a chance to see the new mode. */
+ I830VideoSwitchModeAfter(pScrn, mode);
#endif
+ }
return ret;
}
@@ -5515,7 +5805,7 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen)
pI830->CursorInfoRec = 0;
}
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
xf86GARTCloseScreen(scrnIndex);
xfree(pI830->LpRing);
@@ -5528,8 +5818,11 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen)
pI830->OverlayMem = NULL;
xfree(pI830->overlayOn);
pI830->overlayOn = NULL;
+ xfree(pI830->used3D);
+ pI830->used3D = NULL;
}
+ pScrn->PointerMoved = pI830->PointerMoved;
pScrn->vtSema = FALSE;
pI830->closing = FALSE;
pScreen->CloseScreen = pI830->CloseScreen;
@@ -5568,7 +5861,7 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo)
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX, "Enter VT, event %d, undo: %s\n", event, BOOLTOSTRING(undo));
-
+
switch(event) {
case XF86_APM_SYS_SUSPEND:
case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend?*/
@@ -5603,6 +5896,34 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo)
SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
}
break;
+ /* This is currently used for ACPI */
+ case XF86_APM_CAPABILITY_CHANGED:
+#if 0
+ /* If we had status checking turned on, turn it off now */
+ if (pI830->checkDevices) {
+ if (pI830->devicesTimer)
+ TimerCancel(pI830->devicesTimer);
+ pI830->devicesTimer = NULL;
+ pI830->checkDevices = FALSE;
+ }
+#endif
+ if (!I830IsPrimary(pScrn))
+ return TRUE;
+
+ ErrorF("I830PMEvent: Capability change\n");
+
+ /* ACPI Toggle */
+ pI830->toggleDevices = GetNextDisplayDeviceList(pScrn, 1);
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
+ pI8302->toggleDevices = pI830->toggleDevices;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle to 0x%x\n",pI830->toggleDevices);
+
+ I830CheckDevicesTimer(NULL, 0, pScrn);
+ SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
+ break;
default:
ErrorF("I830PMEvent: received APM event %d\n", event);
}
@@ -5634,28 +5955,40 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
CARD32 adjust;
CARD32 temp = INREG(SWF0) & 0x0000FFFF;
int fixup = 0;
+ I830Ptr pI8301;
+ I830Ptr pI8302 = NULL;
- /* this avoids a BIOS call if possible */
- if (pI830->monitorSwitch != temp) {
- I830Ptr pI8301;
- I830Ptr pI8302 = NULL;
- unsigned int toggle = GetToggleList(pScrn, 1);
+ if (I830IsPrimary(pScrn))
+ pI8301 = pI830;
+ else
+ pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
- GetToggleList(pScrn, 2);
- GetToggleList(pScrn, 3);
- GetToggleList(pScrn, 4);
-
- if (IsPrimary(pScrn))
- pI8301 = pI830;
- else
- pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ if (xf86IsEntityShared(pScrn->entityList[0]))
+ pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
- if (xf86IsEntityShared(pScrn->entityList[0]))
- pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
+ /* this avoids several BIOS calls if possible */
+ if (pI830->monitorSwitch != temp || pI830->monitorSwitch != pI830->toggleDevices) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Hotkey switch to 0x%lx.\n", temp);
+
+ if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+ (*pI830->AccelInfoRec->Sync)(pScrn);
+ pI830->AccelInfoRec->NeedToSync = FALSE;
+ if (xf86IsEntityShared(pScrn->entityList[0]))
+ pI8302->AccelInfoRec->NeedToSync = FALSE;
+ }
+ GetAttachableDisplayDeviceList(pScrn);
+
+ pI8301->lastDevice0 = pI8301->lastDevice1;
pI8301->lastDevice1 = pI8301->lastDevice2;
pI8301->lastDevice2 = pI8301->monitorSwitch;
+ if (temp != pI8301->lastDevice1 &&
+ temp != pI8301->lastDevice2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Detected three device configs.\n");
+ } else
if (CountBits(temp & 0xff) > 1) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Detected cloned pipe mode (A).\n");
@@ -5684,15 +6017,15 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
}
if (cloned &&
- ((CountBits(pI830->lastDevice1 & 0xff) > 1) ||
- ((CountBits((pI830->lastDevice1 & 0xff00) >> 8) > 1))) ) {
+ ((CountBits(pI8301->lastDevice1 & 0xff) > 1) ||
+ ((CountBits((pI8301->lastDevice1 & 0xff00) >> 8) > 1))) ) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Detected duplicate (1).\n");
cloned = 0;
} else
if (cloned &&
- ((CountBits(pI830->lastDevice2 & 0xff) > 1) ||
- ((CountBits((pI830->lastDevice2 & 0xff00) >> 8) > 1))) ) {
+ ((CountBits(pI8301->lastDevice2 & 0xff) > 1) ||
+ ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Detected duplicate (2).\n");
cloned = 0;
@@ -5710,9 +6043,23 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
*
* Cloned pipe mode should only be done when running single head.
*/
- if (xf86IsEntityShared(pScrn->entityList[0]))
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
cloned = 0;
+ /* Some BIOS' don't realize we may be in true dual head mode.
+ * And only display the primary output on both when switching.
+ * We detect this here and cycle back to both pipes.
+ */
+ if ((pI830->lastDevice0 == temp) &&
+ ((CountBits(pI8301->lastDevice2 & 0xff) > 1) ||
+ ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Detected cloned pipe mode when dual head on previous switch. (0x%x -> 0x%x)\n", (int)temp, pI8301->MonType2 << 8 | pI8301->MonType1);
+ temp = pI8301->MonType2 << 8 | pI8301->MonType1;
+ }
+
+ }
+
if (cloned) {
if (pI830->Clone)
temp = pI8301->MonType2 << 8 | pI8301->MonType1;
@@ -5723,8 +6070,8 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
}
/* Jump to our next mode if we detect we've been here before */
- if (temp == pI830->lastDevice1 || temp == pI830->lastDevice2) {
- temp = toggle;
+ if (temp == pI8301->lastDevice1 || temp == pI8301->lastDevice2) {
+ temp = GetToggleList(pScrn, 1);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Detected duplicate devices. Toggling (0x%lx)\n", temp);
}
@@ -5736,6 +6083,24 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
/* So that if we close on the wrong config, we restore correctly */
pI830->specifiedMonitor = TRUE;
+ if (!xf86IsEntityShared(pScrn->entityList[0])) {
+ if ((temp & 0xFF00) && (temp & 0x00FF)) {
+ pI830->Clone = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n");
+ } else {
+ pI830->Clone = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clearing Clone mode\n");
+ }
+ }
+
+ {
+ /* Turn Cursor off before switching */
+ Bool on = pI830->cursorOn;
+ if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor)
+ pI830->CursorInfoRec->HideCursor(pScrn);
+ pI830->cursorOn = on;
+ }
+
/* double check the display devices are what's configured and try
* not to do it twice because of dual heads with the code above */
if (!SetDisplayDevices(pScrn, temp)) {
@@ -5748,20 +6113,37 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
if (!SetDisplayDevices(pScrn, temp))
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch "
"to configured display devices (0x%lx).\n", temp);
- else
+ else {
pI830->Clone = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n");
+ }
}
}
+
pI8301->monitorSwitch = temp;
pI8301->operatingDevices = temp;
+ pI8301->toggleDevices = temp;
+
if (xf86IsEntityShared(pScrn->entityList[0])) {
- pI8302->operatingDevices = temp;
- pI8302->monitorSwitch = temp;
+ pI8302->operatingDevices = pI8301->operatingDevices;
+ pI8302->monitorSwitch = pI8301->monitorSwitch;
+ pI8302->toggleDevices = pI8301->toggleDevices;
}
fixup = 1;
+
+#if 0
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "ACPI _DGS queried devices is 0x%x, but probed is 0x%x monitorSwitch=0x%x\n",
+ pI830->toggleDevices, INREG(SWF0), pI830->monitorSwitch);
+#endif
} else {
- int offset = pScrn->fbOffset + ((pScrn->frameY0 * pScrn->displayWidth + pScrn->frameX0) * pI830->cpp);
+ int offset = -1;
+ if (I830IsPrimary(pScrn))
+ offset = pI8301->FrontBuffer.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp);
+ else {
+ offset = pI8301->FrontBuffer2.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp);
+ }
if (pI830->pipe == 0)
adjust = INREG(DSPABASE);
@@ -5780,6 +6162,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
ScreenPtr pCursorScreen;
int x = 0, y = 0;
+
pCursorScreen = miPointerCurrentScreen();
if (pScrn->pScreen == pCursorScreen)
miPointerPosition(&x, &y);
@@ -5794,13 +6177,15 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
"Primary pipe is now %s.\n", pI830->pipe ? "B" : "A");
}
+ pI830->currentMode = NULL;
I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0);
I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+
if (xf86IsEntityShared(pScrn->entityList[0])) {
ScrnInfoPtr pScrn2;
I830Ptr pI8302;
- if (IsPrimary(pScrn)) {
+ if (I830IsPrimary(pScrn)) {
pScrn2 = pI830->entityPrivate->pScrn_2;
pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
} else {
@@ -5808,8 +6193,16 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
pI8302 = I830PTR(pI830->entityPrivate->pScrn_1);
}
+ if (pScrn2->pScreen == pCursorScreen)
+ miPointerPosition(&x, &y);
+
+ pI8302->currentMode = NULL;
I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0);
I830BIOSAdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
+
+ (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE);
+ (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE);
+
if (pScrn2->pScreen == pCursorScreen) {
int sigstate = xf86BlockSIGIO ();
miPointerWarpCursor(pScrn2->pScreen,x,y);
@@ -5818,12 +6211,16 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
xf86UnblockSIGIO (sigstate);
if (pI8302->CursorInfoRec && !pI8302->SWCursor && pI8302->cursorOn) {
pI8302->CursorInfoRec->HideCursor(pScrn);
+ xf86SetCursor(pScrn2->pScreen, pI830->pCurs, x, y);
pI8302->CursorInfoRec->ShowCursor(pScrn);
pI8302->cursorOn = TRUE;
}
}
}
+ (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, FALSE);
+ (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, TRUE);
+
if (pScrn->pScreen == pCursorScreen) {
int sigstate = xf86BlockSIGIO ();
miPointerWarpCursor(pScrn->pScreen,x,y);
@@ -5832,12 +6229,14 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
xf86UnblockSIGIO (sigstate);
if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
pI830->CursorInfoRec->HideCursor(pScrn);
+ xf86SetCursor(pScrn->pScreen, pI830->pCurs, x, y);
pI830->CursorInfoRec->ShowCursor(pScrn);
pI830->cursorOn = TRUE;
}
}
}
}
+
return 1000;
}
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 27cf0178..84de2c3e 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -61,6 +61,27 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830.h"
#include "i810_reg.h"
+static int nextTile = 0;
+static unsigned int tileGeneration = -1;
+
+#ifndef ALLOCATE_ALL_BIOSMEM
+#define ALLOCATE_ALL_BIOSMEM 1
+#endif
+
+static unsigned long
+GetBestTileAlignment(unsigned long size)
+{
+ unsigned long i;
+
+ for (i = KB(512); i < size; i <<= 1)
+ ;
+
+ if (i > MB(64))
+ i = MB(64);
+
+ return i;
+}
+
/*
* Allocate memory from the given pool. Grow the pool if needed and if
* possible.
@@ -212,6 +233,59 @@ AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, long size,
return size;
}
+void
+I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (!range || range->Size == 0)
+ return;
+
+ if (range->Key != -1)
+ xf86DeallocateGARTMemory(pScrn->scrnIndex, range->Key);
+
+ if (range->Pool) {
+ /*
+ * This code essentially resets what I830DoPoolAllocation() did.
+ * And if things are freed in the wrong order this can break wildly!
+ * USE CAUTION when changing anything here...
+ */
+ I830MemPool *Pool = range->Pool;
+ if (pI830->overrideBIOSMemSize &&
+ pI830->BIOSMemorySize > pI830->StolenMemory.Size)
+ Pool->Total.End = pI830->BIOSMemorySize;
+ else
+ Pool->Total.End = pI830->StolenMemory.End;
+
+ if (pI830->StolenOnly)
+ Pool->Free.End += range->Size;
+ else
+ Pool->Free.End = Pool->Total.End;
+
+ if (Pool->Free.End < Pool->Free.Start) {
+ Pool->Free.End = Pool->Free.Start;
+ }
+
+ Pool->Free.Size = Pool->Free.End - Pool->Free.Start;
+ Pool->Total.Size = Pool->Total.End - Pool->Total.Start;
+
+ if (!pI830->StolenOnly) {
+ pI830->FreeMemory -= Pool->Free.Size;
+ pI830->MemoryAperture.Start -= (range->Size - Pool->Free.Size);
+ pI830->MemoryAperture.Size += (range->Size - Pool->Free.Size);
+ }
+ } else {
+ if (range->Alignment == GTT_PAGE_SIZE)
+ pI830->MemoryAperture.End = range->End;
+ else
+ pI830->MemoryAperture.End = range->End - range->Size + range->Alignment;
+ pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start;
+ }
+
+ if (!pI830->StolenOnly)
+ pI830->FreeMemory += range->Size;
+ pI830->allocatedMemory -= range->Size;
+}
unsigned long
I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool,
@@ -345,25 +419,30 @@ AllocateOverlay(ScrnInfoPtr pScrn, int flags)
alloced / 1024, pI830->OverlayMem->Start,
pI830->OverlayMem->Physical);
}
- return TRUE;
-}
-#endif
-static unsigned long
-GetFreeSpace(ScrnInfoPtr pScrn)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long extra = 0;
+ /* Clear linearmem info */
+ if (pI830->LinearAlloc) {
+ memset(&(pI830->LinearMem), 0, sizeof(I830MemRange));
+ pI830->LinearMem.Key = -1;
- /* First check for free space in StolenPool. */
- if (pI830->StolenPool.Free.Size > 0)
- extra = pI830->StolenPool.Free.Size;
- /* Next check for unallocated space. */
- if (pI830->FreeMemory > 0)
- extra += pI830->FreeMemory;
+ size = KB(pI830->LinearAlloc);
+ alloced = I830AllocVidMem(pScrn, &(pI830->LinearMem), &(pI830->StolenPool),
+ size, GTT_PAGE_SIZE,
+ FROM_ANYWHERE | ALLOCATE_AT_TOP);
+ if (alloced < size) {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate linear buffer space\n");
+ }
+ } else
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocated %ld kB for the linear buffer at 0x%lx\n", s,
+ alloced / 1024, pI830->LinearMem.Start);
+ }
- return extra;
+ return TRUE;
}
+#endif
static Bool
IsTileable(int pitch)
@@ -386,6 +465,150 @@ IsTileable(int pitch)
}
}
+Bool
+I830AllocateRotatedBuffer(ScrnInfoPtr pScrn, int flags)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size, alloced;
+ Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
+ int verbosity = dryrun ? 4 : 1;
+ const char *s = dryrun ? "[dryrun] " : "";
+ int align;
+ Bool tileable;
+ int lines;
+ int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX;
+
+ /* Rotated Buffer */
+ memset(&(pI830->RotatedMem), 0, sizeof(I830MemRange));
+ pI830->RotatedMem.Key = -1;
+ tileable = !(flags & ALLOC_NO_TILING) &&
+ IsTileable(pScrn->displayWidth * pI830->cpp);
+ if (tileable) {
+ /* Make the height a multiple of the tile height (16) */
+ lines = (height + 15) / 16 * 16;
+ } else {
+ lines = height;
+ }
+
+ size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp);
+ /*
+ * Try to allocate on the best tile-friendly boundaries.
+ */
+ alloced = 0;
+ if (tileable) {
+ align = GetBestTileAlignment(size);
+ for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+ alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem),
+ &(pI830->StolenPool), size, align,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
+ ALIGN_BOTH_ENDS);
+ if (alloced >= size)
+ break;
+ }
+ }
+ if (alloced < size) {
+ /* Give up on trying to tile */
+ tileable = FALSE;
+ size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp);
+ align = GTT_PAGE_SIZE;
+ alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem),
+ &(pI830->StolenPool), size, align,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
+ }
+ if (alloced < size) {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate rotated buffer space.\n");
+ }
+ return FALSE;
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocated %ld kB for the rotated buffer at 0x%lx.\n", s,
+ alloced / 1024, pI830->RotatedMem.Start);
+ return TRUE;
+}
+
+Bool
+I830AllocateRotated2Buffer(ScrnInfoPtr pScrn, int flags)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size, alloced;
+ Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
+ int verbosity = dryrun ? 4 : 1;
+ const char *s = dryrun ? "[dryrun] " : "";
+ int align;
+ Bool tileable;
+ int lines;
+ I830EntPtr pI830Ent = pI830->entityPrivate;
+ I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2);
+ int height = (pI8302->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pI830Ent->pScrn_2->virtualY : pI830Ent->pScrn_2->virtualX;
+
+ /* Rotated Buffer */
+ memset(&(pI830->RotatedMem2), 0, sizeof(I830MemRange));
+ pI830->RotatedMem2.Key = -1;
+ tileable = !(flags & ALLOC_NO_TILING) &&
+ IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp);
+ if (tileable) {
+ /* Make the height a multiple of the tile height (16) */
+ lines = (height + 15) / 16 * 16;
+ } else {
+ lines = height;
+ }
+
+ size = ROUND_TO_PAGE(pI830Ent->pScrn_2->displayWidth * lines * pI8302->cpp);
+ /*
+ * Try to allocate on the best tile-friendly boundaries.
+ */
+ alloced = 0;
+ if (tileable) {
+ align = GetBestTileAlignment(size);
+ for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+ alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem2),
+ &(pI830->StolenPool), size, align,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
+ ALIGN_BOTH_ENDS);
+ if (alloced >= size)
+ break;
+ }
+ }
+ if (alloced < size) {
+ /* Give up on trying to tile */
+ tileable = FALSE;
+ size = ROUND_TO_PAGE(pI830Ent->pScrn_2->displayWidth * height * pI8302->cpp);
+ align = GTT_PAGE_SIZE;
+ alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem2),
+ &(pI830->StolenPool), size, align,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
+ }
+ if (alloced < size) {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate rotated2 buffer space.\n");
+ }
+ return FALSE;
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocated %ld kB for the rotated2 buffer at 0x%lx.\n", s,
+ alloced / 1024, pI830->RotatedMem2.Start);
+ return TRUE;
+}
+
+static unsigned long
+GetFreeSpace(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long extra = 0;
+
+ /* First check for free space in StolenPool. */
+ if (pI830->StolenPool.Free.Size > 0)
+ extra = pI830->StolenPool.Free.Size;
+ /* Next check for unallocated space. */
+ if (pI830->FreeMemory > 0)
+ extra += pI830->FreeMemory;
+
+ return extra;
+}
+
/*
* Allocate memory for 2D operation. This includes the (front) framebuffer,
* ring buffer, scratch memory, HW cursor.
@@ -452,7 +675,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
pI830->FbMemBox2.x1 = 0;
pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
pI830->FbMemBox2.y1 = 0;
- pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
+ if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY)
+ pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualX;
+ else
+ pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
/*
* Calculate how much framebuffer memory to allocate. For the
@@ -511,8 +737,12 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
alignflags = 0;
}
- size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
+ if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY)
+ size = lineSize * (pI830Ent->pScrn_2->virtualX + cacheLines);
+ else
+ size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
size = ROUND_TO_PAGE(size);
+
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sSecondary framebuffer allocation size: %ld kByte\n", s,
size / 1024);
@@ -537,7 +767,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
pI830->FbMemBox.x1 = 0;
pI830->FbMemBox.x2 = pScrn->displayWidth;
pI830->FbMemBox.y1 = 0;
- pI830->FbMemBox.y2 = pScrn->virtualY;
+ if (pScrn->virtualX > pScrn->virtualY)
+ pI830->FbMemBox.y2 = pScrn->virtualX;
+ else
+ pI830->FbMemBox.y2 = pScrn->virtualY;
/*
* Calculate how much framebuffer memory to allocate. For the
@@ -596,8 +829,12 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
alignflags = 0;
}
- size = lineSize * (pScrn->virtualY + cacheLines);
+ if (pScrn->virtualX > pScrn->virtualY)
+ size = lineSize * (pScrn->virtualX + cacheLines);
+ else
+ size = lineSize * (pScrn->virtualY + cacheLines);
size = ROUND_TO_PAGE(size);
+
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sInitial framebuffer allocation size: %ld kByte\n", s,
size / 1024);
@@ -633,7 +870,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
maxFb = ROUND_DOWN_TO(maxFb, lineSize);
if (maxFb > lineSize * MAX_DISPLAY_HEIGHT)
maxFb = lineSize * MAX_DISPLAY_HEIGHT;
- if (maxFb > pI830->FrontBuffer.Size) {
+ if (0/*maxFb > pI830->FrontBuffer.Size*/) {
unsigned long oldsize;
/*
* Sanity check -- the fb should be the last thing allocated at
@@ -699,8 +936,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
*/
if (!dryrun) {
memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy));
- pI830->Dummy.Key =
- xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+ pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
pI830->Dummy.Offset = 0;
}
#endif
@@ -827,13 +1063,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
alloced / 1024, pI830->Scratch2.Start);
}
}
+
return TRUE;
}
-#ifndef ALLOCATE_ALL_BIOSMEM
-#define ALLOCATE_ALL_BIOSMEM 1
-#endif
-
void
I830ResetAllocations(ScrnInfoPtr pScrn, const int flags)
{
@@ -870,20 +1103,6 @@ I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn)
}
#ifdef XF86DRI
-static unsigned long
-GetBestTileAlignment(unsigned long size)
-{
- unsigned long i;
-
- for (i = KB(512); i < size; i <<= 1)
- ;
-
- if (i > MB(64))
- i = MB(64);
-
- return i;
-}
-
static unsigned int
myLog2(unsigned int n)
{
@@ -897,18 +1116,16 @@ myLog2(unsigned int n)
}
Bool
-I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
+I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags)
{
I830Ptr pI830 = I830PTR(pScrn);
unsigned long size, alloced, align = 0;
- int i;
Bool tileable;
Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
int verbosity = dryrun ? 4 : 1;
const char *s = dryrun ? "[dryrun] " : "";
int lines;
-
- DPRINTF(PFX, "I830Allocate3DMemory\n");
+ int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX;
/* Back Buffer */
memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer));
@@ -917,9 +1134,9 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
IsTileable(pScrn->displayWidth * pI830->cpp);
if (tileable) {
/* Make the height a multiple of the tile height (16) */
- lines = (pScrn->virtualY + 15) / 16 * 16;
+ lines = (height + 15) / 16 * 16;
} else {
- lines = pScrn->virtualY;
+ lines = height;
}
size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp);
@@ -941,7 +1158,7 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
if (alloced < size) {
/* Give up on trying to tile */
tileable = FALSE;
- size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp);
+ size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp);
align = GTT_PAGE_SIZE;
alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer),
&(pI830->StolenPool), size, align,
@@ -958,16 +1175,41 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
"%sAllocated %ld kB for the back buffer at 0x%lx.\n", s,
alloced / 1024, pI830->BackBuffer.Start);
+ return TRUE;
+}
+
+Bool
+I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size, alloced, align = 0;
+ Bool tileable;
+ Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
+ int verbosity = dryrun ? 4 : 1;
+ const char *s = dryrun ? "[dryrun] " : "";
+ int lines;
+ int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX;
+
/* Depth Buffer -- same size as the back buffer */
memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer));
pI830->DepthBuffer.Key = -1;
+ tileable = !(flags & ALLOC_NO_TILING) &&
+ IsTileable(pScrn->displayWidth * pI830->cpp);
+ if (tileable) {
+ /* Make the height a multiple of the tile height (16) */
+ lines = (height + 15) / 16 * 16;
+ } else {
+ lines = height;
+ }
+
+ size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp);
/*
* Try to allocate on the best tile-friendly boundaries.
*/
alloced = 0;
if (tileable) {
- /* Start with the previous align value. */
- for (; align >= KB(512); align >>= 1) {
+ align = GetBestTileAlignment(size);
+ for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
&(pI830->StolenPool), size, align,
flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -979,7 +1221,7 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
if (alloced < size) {
/* Give up on trying to tile */
tileable = FALSE;
- size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp);
+ size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp);
align = GTT_PAGE_SIZE;
alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
&(pI830->StolenPool), size, align,
@@ -996,24 +1238,18 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
"%sAllocated %ld kB for the depth buffer at 0x%lx.\n", s,
alloced / 1024, pI830->DepthBuffer.Start);
- /* Space for logical context. 32k is fine for right now. */
- memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem));
- pI830->ContextMem.Key = -1;
- size = KB(32);
- alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem),
- &(pI830->StolenPool), size, GTT_PAGE_SIZE,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate logical context space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the logical context at 0x%lx.\n", s,
- alloced / 1024, pI830->ContextMem.Start);
+ return TRUE;
+}
+Bool
+I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size, alloced;
+ int i;
+ Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
+ int verbosity = dryrun ? 4 : 1;
+ const char *s = dryrun ? "[dryrun] " : "";
/* Allocate the remaining space for textures. */
memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem));
@@ -1052,6 +1288,47 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
return TRUE;
}
+
+Bool
+I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size, alloced;
+ Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
+ int verbosity = dryrun ? 4 : 1;
+ const char *s = dryrun ? "[dryrun] " : "";
+
+ DPRINTF(PFX, "I830Allocate3DMemory\n");
+
+ /* Space for logical context. 32k is fine for right now. */
+ memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem));
+ pI830->ContextMem.Key = -1;
+ size = KB(32);
+ alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem),
+ &(pI830->StolenPool), size, GTT_PAGE_SIZE,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
+ if (alloced < size) {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate logical context space.\n");
+ }
+ return FALSE;
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocated %ld kB for the logical context at 0x%lx.\n", s,
+ alloced / 1024, pI830->ContextMem.Start);
+
+ if (!I830AllocateBackBuffer(pScrn, flags))
+ return FALSE;
+
+ if (!I830AllocateDepthBuffer(pScrn, flags))
+ return FALSE;
+
+ if (!I830AllocateTextureMemory(pScrn, flags))
+ return FALSE;
+
+ return TRUE;
+}
#endif
/* Allocate pool space that isn't pre-allocated */
@@ -1079,9 +1356,8 @@ I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool)
if (pool->Total.Size > pool->Fixed.Size) {
pool->Allocated.Size = pool->Total.Size - pool->Fixed.Size;
- pool->Allocated.Key =
- xf86AllocateGARTMemory(pScrn->scrnIndex, pool->Allocated.Size,
- 0, NULL);
+ pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex,
+ pool->Allocated.Size, 0, NULL);
if (pool->Allocated.Key == -1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n");
return FALSE;
@@ -1115,8 +1391,8 @@ static unsigned long topOfMem = 0;
#define PACK_RANGES 0
#define POOL_RANGES 0
-static Bool
-FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem)
+Bool
+I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem)
{
#if POOL_RANGES
I830Ptr pI830 = I830PTR(pScrn);
@@ -1186,25 +1462,27 @@ I830FixupOffsets(ScrnInfoPtr pScrn)
topOfMem = pI830->StolenPool.Total.End;
if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- FixOffset(pScrn, &(pI830->FrontBuffer2));
- FixOffset(pScrn, &(pI830->FrontBuffer));
- FixOffset(pScrn, pI830->CursorMem);
- FixOffset(pScrn, pI830->CursorMemARGB);
- FixOffset(pScrn, &(pI830->LpRing->mem));
- FixOffset(pScrn, &(pI830->Scratch));
+ I830FixOffset(pScrn, &(pI830->FrontBuffer2));
+ I830FixOffset(pScrn, &(pI830->FrontBuffer));
+ I830FixOffset(pScrn, pI830->CursorMem);
+ I830FixOffset(pScrn, pI830->CursorMemARGB);
+ I830FixOffset(pScrn, &(pI830->LpRing->mem));
+ I830FixOffset(pScrn, &(pI830->Scratch));
if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- FixOffset(pScrn, &(pI830->Scratch2));
+ I830FixOffset(pScrn, &(pI830->Scratch2));
#ifdef I830_XV
if (pI830->XvEnabled) {
- FixOffset(pScrn, pI830->OverlayMem);
+ I830FixOffset(pScrn, pI830->OverlayMem);
+ if (pI830->LinearAlloc)
+ I830FixOffset(pScrn, &(pI830->LinearMem));
}
#endif
#ifdef XF86DRI
if (pI830->directRenderingEnabled) {
- FixOffset(pScrn, &(pI830->BackBuffer));
- FixOffset(pScrn, &(pI830->DepthBuffer));
- FixOffset(pScrn, &(pI830->ContextMem));
- FixOffset(pScrn, &(pI830->TexMem));
+ I830FixOffset(pScrn, &(pI830->ContextMem));
+ I830FixOffset(pScrn, &(pI830->BackBuffer));
+ I830FixOffset(pScrn, &(pI830->DepthBuffer));
+ I830FixOffset(pScrn, &(pI830->TexMem));
}
#endif
return TRUE;
@@ -1239,7 +1517,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
i830Reg->Fence[nr] = 0;
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
+ if (IS_I9XX(pI830))
fence_mask = ~I915G_FENCE_START_MASK;
else
fence_mask = ~I830_FENCE_START_MASK;
@@ -1247,7 +1525,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
if (start & fence_mask) {
xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
"SetFence: %d: start (0x%08x) is not %s aligned\n",
- nr, start, (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) ? "1MB" : "512k");
+ nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k");
return;
}
@@ -1267,7 +1545,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
val = (start | FENCE_X_MAJOR | FENCE_VALID);
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
+ if (IS_I9XX(pI830)) {
switch (size) {
case MB(1):
val |= I915G_FENCE_SIZE_1M;
@@ -1328,7 +1606,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
}
}
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
+ if (IS_I9XX(pI830))
fence_pitch = pitch / 512;
else
fence_pitch = pitch / 128;
@@ -1369,8 +1647,6 @@ MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem)
{
I830Ptr pI830 = I830PTR(pScrn);
int pitch, ntiles, i;
- static int nextTile = 0;
- static unsigned int tileGeneration = -1;
#if 0
/* Hack to "improve" the alignment of the front buffer.
@@ -1405,6 +1681,14 @@ void
I830SetupMemoryTiling(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
+ int i;
+
+ /* Clear out */
+ for (i = 0; i < 8; i++)
+ pI830->ModeReg.Fence[i] = 0;
+
+ nextTile = 0;
+ tileGeneration = -1;
/* We currently only attempt to tile the back and depth buffers. */
if (!pI830->directRenderingEnabled)
@@ -1458,10 +1742,31 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
"Activating tiled memory for the depth buffer.\n");
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MakeTiles failed for the back buffer.\n");
+ "MakeTiles failed for the depth buffer.\n");
}
}
+ if (pI830->RotatedMem.Alignment >= KB(512)) {
+ if (MakeTiles(pScrn, &(pI830->RotatedMem))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Activating tiled memory for the rotated buffer.\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "MakeTiles failed for the rotated buffer.\n");
+ }
+ }
+
+#if 0
+ if (pI830->RotatedMem2.Alignment >= KB(512)) {
+ if (MakeTiles(pScrn, &(pI830->RotatedMem2))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Activating tiled memory for the rotated2 buffer.\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "MakeTiles failed for the rotated buffer.\n");
+ }
+ }
+#endif
}
#endif /* XF86DRI */
@@ -1478,12 +1783,12 @@ BindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem)
}
Bool
-I830BindGARTMemory(ScrnInfoPtr pScrn)
+I830BindAGPMemory(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX,
- "I830BindGARTMemory: StolenOnly is %s, pI830->GttBound is %s\n",
+ "I830BindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n",
BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound));
if (pI830->StolenOnly == TRUE)
@@ -1517,17 +1822,29 @@ I830BindGARTMemory(ScrnInfoPtr pScrn)
if (!BindMemRange(pScrn, &(pI830->Scratch2)))
return FALSE;
#ifdef I830_XV
- if (!BindMemRange(pScrn, pI830->OverlayMem))
- return FALSE;
+ if (pI830->XvEnabled) {
+ if (!BindMemRange(pScrn, pI830->OverlayMem))
+ return FALSE;
+ if (pI830->LinearAlloc)
+ if (!BindMemRange(pScrn, &(pI830->LinearMem)))
+ return FALSE;
+ }
#endif
+ if (pI830->RotatedMem.Start)
+ if (!BindMemRange(pScrn, &(pI830->RotatedMem)))
+ return FALSE;
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2 &&
+ pI830->RotatedMem2.Start)
+ if (!BindMemRange(pScrn, &(pI830->RotatedMem2)))
+ return FALSE;
#ifdef XF86DRI
if (pI830->directRenderingEnabled) {
+ if (!BindMemRange(pScrn, &(pI830->ContextMem)))
+ return FALSE;
if (!BindMemRange(pScrn, &(pI830->BackBuffer)))
return FALSE;
if (!BindMemRange(pScrn, &(pI830->DepthBuffer)))
return FALSE;
- if (!BindMemRange(pScrn, &(pI830->ContextMem)))
- return FALSE;
if (!BindMemRange(pScrn, &(pI830->TexMem)))
return FALSE;
}
@@ -1552,12 +1869,12 @@ UnbindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem)
Bool
-I830UnbindGARTMemory(ScrnInfoPtr pScrn)
+I830UnbindAGPMemory(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX,
- "I830UnbindGARTMemory: StolenOnly is %s, pI830->GttBound is %s\n",
+ "I830UnbindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n",
BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound));
if (pI830->StolenOnly == TRUE)
@@ -1589,17 +1906,29 @@ I830UnbindGARTMemory(ScrnInfoPtr pScrn)
if (!UnbindMemRange(pScrn, &(pI830->Scratch2)))
return FALSE;
#ifdef I830_XV
- if (!UnbindMemRange(pScrn, pI830->OverlayMem))
- return FALSE;
+ if (pI830->XvEnabled) {
+ if (!UnbindMemRange(pScrn, pI830->OverlayMem))
+ return FALSE;
+ if (pI830->LinearAlloc)
+ if (!UnbindMemRange(pScrn, &(pI830->LinearMem)))
+ return FALSE;
+ }
#endif
+ if (pI830->RotatedMem.Start)
+ if (!UnbindMemRange(pScrn, &(pI830->RotatedMem)))
+ return FALSE;
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2 &&
+ pI830->RotatedMem2.Start)
+ if (!UnbindMemRange(pScrn, &(pI830->RotatedMem2)))
+ return FALSE;
#ifdef XF86DRI
if (pI830->directRenderingEnabled) {
+ if (!UnbindMemRange(pScrn, &(pI830->ContextMem)))
+ return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->BackBuffer)))
return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer)))
return FALSE;
- if (!UnbindMemRange(pScrn, &(pI830->ContextMem)))
- return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->TexMem)))
return FALSE;
}
@@ -1617,7 +1946,7 @@ long
I830CheckAvailableMemory(ScrnInfoPtr pScrn)
{
AgpInfoPtr agpinf;
- long maxPages;
+ int maxPages;
if (!xf86AgpGARTSupported() ||
!xf86AcquireGART(pScrn->scrnIndex) ||
@@ -1626,9 +1955,8 @@ I830CheckAvailableMemory(ScrnInfoPtr pScrn)
return -1;
maxPages = agpinf->totalPages - agpinf->usedPages;
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,
- "Checking Available AGP Memory: %ld kB available (total %ld kB, used %ld kB)\n",
- maxPages * 4, agpinf->totalPages * 4, agpinf->usedPages * 4);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n",
+ "I830CheckAvailableMemory", maxPages * 4);
return maxPages * 4;
}
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 457b583e..a992bb60 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -346,7 +346,7 @@ I830GetGTF (int h_pixels, int v_lines, float freq,
m->Clock = (int)(pixel_freq * 1000);
m->SynthClock = m->Clock;
m->HSync = h_freq;
- m->VRefresh = freq;
+ m->VRefresh = v_frame_rate /* freq */;
snprintf(modename, sizeof(modename), "%dx%d", m->HDisplay,m->VDisplay);
m->name = xnfstrdup(modename);
diff --git a/src/i830_randr.c b/src/i830_randr.c
new file mode 100644
index 00000000..be790c9a
--- /dev/null
+++ b/src/i830_randr.c
@@ -0,0 +1,356 @@
+/* $XdotOrg: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.3 2004/07/30 21:53:09 eich Exp $ */
+/*
+ * $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.7tsi Exp $
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xf86.h"
+#include "os.h"
+#include "mibank.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86DDC.h"
+#include "mipointer.h"
+#include "windowstr.h"
+#include <randrstr.h>
+
+#include "i830.h"
+
+typedef struct _i830RandRInfo {
+ int virtualX;
+ int virtualY;
+ int mmWidth;
+ int mmHeight;
+ int maxX;
+ int maxY;
+ Rotation rotation; /* current mode */
+ Rotation supported_rotations; /* driver supported */
+} XF86RandRInfoRec, *XF86RandRInfoPtr;
+
+static int i830RandRIndex;
+static int i830RandRGeneration;
+
+#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[i830RandRIndex].ptr)
+
+static int
+I830RandRModeRefresh (DisplayModePtr mode)
+{
+ if (mode->VRefresh)
+ return (int) (mode->VRefresh + 0.5);
+ else
+ return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
+}
+
+static Bool
+I830RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ RRScreenSizePtr pSize;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int refresh0 = 60;
+ int maxX = 0, maxY = 0;
+
+ *rotations = randrp->supported_rotations;
+
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = scrp->virtualX;
+ randrp->virtualY = scrp->virtualY;
+ }
+
+ for (mode = scrp->modes; ; mode = mode->next)
+ {
+ int refresh = I830RandRModeRefresh (mode);
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ if (maxX < mode->HDisplay)
+ maxX = mode->HDisplay;
+ if (maxY < mode->VDisplay)
+ maxY = mode->VDisplay;
+ }
+ if (mode == scrp->modes)
+ refresh0 = refresh;
+ pSize = RRRegisterSize (pScreen,
+ mode->HDisplay, mode->VDisplay,
+ randrp->mmWidth, randrp->mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh);
+ if (mode == scrp->currentMode &&
+ mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
+ if (mode->next == scrp->modes)
+ break;
+ }
+
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ randrp->maxX = maxX;
+ randrp->maxY = maxY;
+ }
+
+ if (scrp->currentMode->HDisplay != randrp->virtualX ||
+ scrp->currentMode->VDisplay != randrp->virtualY)
+ {
+ mode = scrp->modes;
+ pSize = RRRegisterSize (pScreen,
+ randrp->virtualX, randrp->virtualY,
+ randrp->mmWidth,
+ randrp->mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh0);
+ if (scrp->virtualX == randrp->virtualX &&
+ scrp->virtualY == randrp->virtualY)
+ {
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool
+I830RandRSetMode (ScreenPtr pScreen,
+ DisplayModePtr mode,
+ Bool useVirtual,
+ int mmWidth,
+ int mmHeight)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int oldWidth = pScreen->width;
+ int oldHeight = pScreen->height;
+ int oldmmWidth = pScreen->mmWidth;
+ int oldmmHeight = pScreen->mmHeight;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ DisplayModePtr currentMode = NULL;
+ Bool ret = TRUE;
+ PixmapPtr pspix = NULL;
+
+ if (pRoot)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+ if (useVirtual)
+ {
+ scrp->virtualX = randrp->virtualX;
+ scrp->virtualY = randrp->virtualY;
+ }
+ else
+ {
+ scrp->virtualX = mode->HDisplay;
+ scrp->virtualY = mode->VDisplay;
+ }
+ if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
+ {
+ /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
+ pScreen->width = scrp->virtualY;
+ pScreen->height = scrp->virtualX;
+ pScreen->mmWidth = mmHeight;
+ pScreen->mmHeight = mmWidth;
+ }
+ else
+ {
+ pScreen->width = scrp->virtualX;
+ pScreen->height = scrp->virtualY;
+ pScreen->mmWidth = mmWidth;
+ pScreen->mmHeight = mmHeight;
+ }
+ if (scrp->currentMode == mode) {
+ /* Save current mode */
+ currentMode = scrp->currentMode;
+ /* Reset, just so we ensure the drivers SwitchMode is called */
+ scrp->currentMode = NULL;
+ }
+ /*
+ * We know that if the driver failed to SwitchMode to the rotated
+ * version, then it should revert back to it's prior mode.
+ */
+ if (!xf86SwitchMode (pScreen, mode))
+ {
+ ret = FALSE;
+ scrp->virtualX = pScreen->width = oldWidth;
+ scrp->virtualY = pScreen->height = oldHeight;
+ pScreen->mmWidth = oldmmWidth;
+ pScreen->mmHeight = oldmmHeight;
+ scrp->currentMode = currentMode;
+ }
+ /*
+ * Get the new Screen pixmap ptr as SwitchMode might have called
+ * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
+ * Unfortunately.
+ */
+ pspix = (*pScreen->GetScreenPixmap) (pScreen);
+ if (pspix->devPrivate.ptr)
+ scrp->pixmapPrivate = pspix->devPrivate;
+
+ /*
+ * Make sure the layout is correct
+ */
+ xf86ReconfigureLayout();
+
+ /*
+ * Make sure the whole screen is visible
+ */
+ xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+ xf86SetViewport (pScreen, 0, 0);
+ if (pRoot)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+ return ret;
+}
+
+Bool
+I830RandRSetConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int px, py;
+ Bool useVirtual = FALSE;
+ int maxX = 0, maxY = 0;
+ Rotation oldRotation = randrp->rotation;
+
+ randrp->rotation = rotation;
+
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = scrp->virtualX;
+ randrp->virtualY = scrp->virtualY;
+ }
+
+ miPointerPosition (&px, &py);
+ for (mode = scrp->modes; ; mode = mode->next)
+ {
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ if (maxX < mode->HDisplay)
+ maxX = mode->HDisplay;
+ if (maxY < mode->VDisplay)
+ maxY = mode->VDisplay;
+ }
+ if (mode->HDisplay == pSize->width &&
+ mode->VDisplay == pSize->height &&
+ (rate == 0 || I830RandRModeRefresh (mode) == rate))
+ break;
+ if (mode->next == scrp->modes)
+ {
+ if (pSize->width == randrp->virtualX &&
+ pSize->height == randrp->virtualY)
+ {
+ mode = scrp->modes;
+ useVirtual = TRUE;
+ break;
+ }
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ randrp->maxX = maxX;
+ randrp->maxY = maxY;
+ }
+ return FALSE;
+ }
+ }
+
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ randrp->maxX = maxX;
+ randrp->maxY = maxY;
+ }
+
+ if (!I830RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
+ randrp->rotation = oldRotation;
+ return FALSE;
+ }
+
+ /*
+ * Move the cursor back where it belongs; SwitchMode repositions it
+ */
+ if (pScreen == miPointerCurrentScreen ())
+ {
+ px = (px >= pScreen->width ? (pScreen->width - 1) : px);
+ py = (py >= pScreen->height ? (pScreen->height - 1) : py);
+
+ xf86SetViewport(pScreen, px, py);
+
+ (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
+ }
+
+ return TRUE;
+}
+
+Rotation
+I830GetRotation(ScreenPtr pScreen)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ return randrp->rotation;
+}
+
+Bool
+I830RandRInit (ScreenPtr pScreen, int rotation)
+{
+ rrScrPrivPtr rp;
+ XF86RandRInfoPtr randrp;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+
+#ifdef PANORAMIX
+ /* XXX disable RandR when using Xinerama */
+ if (!noPanoramiXExtension)
+ return TRUE;
+#endif
+ if (i830RandRGeneration != serverGeneration)
+ {
+ i830RandRIndex = AllocateScreenPrivateIndex();
+ i830RandRGeneration = serverGeneration;
+ }
+
+ randrp = xalloc (sizeof (XF86RandRInfoRec));
+ if (!randrp)
+ return FALSE;
+
+ if (!RRScreenInit(pScreen))
+ {
+ xfree (randrp);
+ return FALSE;
+ }
+ rp = rrGetScrPriv(pScreen);
+ rp->rrGetInfo = I830RandRGetInfo;
+ rp->rrSetConfig = I830RandRSetConfig;
+
+ randrp->virtualX = -1;
+ randrp->virtualY = -1;
+ randrp->mmWidth = pScreen->mmWidth;
+ randrp->mmHeight = pScreen->mmHeight;
+
+ randrp->rotation = RR_Rotate_0; /* initial rotated mode */
+
+ randrp->supported_rotations = rotation;
+
+ randrp->maxX = randrp->maxY = 0;
+
+ pScreen->devPrivates[i830RandRIndex].ptr = randrp;
+
+ return TRUE;
+}
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
new file mode 100644
index 00000000..f60d64fe
--- /dev/null
+++ b/src/i830_rotate.c
@@ -0,0 +1,1181 @@
+/**************************************************************************
+
+Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Reformatted with GNU indent (2.2.8), using the following options:
+ *
+ * -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78
+ * -lp -npcs -psl -sob -ss -br -ce -sc -hnl
+ *
+ * This provides a good match with the original i810 code and preferred
+ * XFree86 formatting conventions.
+ *
+ * When editing this driver, please follow the existing formatting, and edit
+ * with <TAB> characters expanded at 8-column intervals.
+ */
+
+/*
+ * Authors:
+ * Alan Hourihane <alanh@tungstengraphics.com>
+ * Brian Paul <brian.paul@tungstengraphics.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "servermd.h"
+#include "shadow.h"
+
+#include "i830.h"
+
+#ifdef XF86DRI
+#include "dri.h"
+#endif
+
+static void *
+I830WindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD8 *ptr;
+
+ *size = (pScrn->bitsPerPixel * pI830->displayWidth >> 3);
+ if (I830IsPrimary(pScrn))
+ ptr = (CARD8 *) (pI830->FbBase + pI830->FrontBuffer.Start) + row * (*size) + offset;
+ else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ ptr = (CARD8 *) (pI830->FbBase + pI8301->FrontBuffer2.Start) + row * (*size) + offset;
+ }
+ return (void *)ptr;
+}
+
+struct matrix23
+{
+ int m00, m01, m02;
+ int m10, m11, m12;
+};
+
+static void
+matrix23Set(struct matrix23 *m,
+ int m00, int m01, int m02,
+ int m10, int m11, int m12)
+{
+ m->m00 = m00; m->m01 = m01; m->m02 = m02;
+ m->m10 = m10; m->m11 = m11; m->m12 = m12;
+}
+
+
+/*
+ * Transform (x,y) coordinate by the given matrix.
+ */
+static void
+matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y)
+{
+ const float x0 = *x;
+ const float y0 = *y;
+
+ *x = m->m00 * x0 + m->m01 * y0 + m->m02;
+ *y = m->m10 * x0 + m->m11 * y0 + m->m12;
+}
+
+/*
+ * Make rotation matrix for width X height screen.
+ */
+static void
+matrix23Rotate(struct matrix23 *m, int width, int height, int angle)
+{
+ switch (angle) {
+ case 0:
+ matrix23Set(m, 1, 0, 0, 0, 1, 0);
+ break;
+ case 90:
+ matrix23Set(m, 0, 1, 0, -1, 0, width);
+ break;
+ case 180:
+ matrix23Set(m, -1, 0, width, 0, -1, height);
+ break;
+ case 270:
+ matrix23Set(m, 0, -1, height, 1, 0, 0);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Doesn't matter on the order for our purposes */
+typedef struct {
+ unsigned char red, green, blue, alpha;
+} intel_color_t;
+
+/* Vertex format */
+typedef union {
+ struct {
+ float x, y, z, w;
+ intel_color_t color;
+ intel_color_t specular;
+ float u0, v0;
+ float u1, v1;
+ float u2, v2;
+ float u3, v3;
+ } v;
+ float f[24];
+ unsigned int ui[24];
+ unsigned char ub4[24][4];
+} intelVertex, *intelVertexPtr;
+
+static void draw_poly(CARD32 *vb,
+ float verts[][2],
+ float texcoords[][2])
+{
+ int vertex_size = 8;
+ intelVertex tmp;
+ int i, k;
+
+ /* initial constant vertex fields */
+ tmp.v.z = 1.0;
+ tmp.v.w = 1.0;
+ tmp.v.color.red = 255;
+ tmp.v.color.green = 255;
+ tmp.v.color.blue = 255;
+ tmp.v.color.alpha = 255;
+ tmp.v.specular.red = 0;
+ tmp.v.specular.green = 0;
+ tmp.v.specular.blue = 0;
+ tmp.v.specular.alpha = 0;
+
+ for (k = 0; k < 4; k++) {
+ tmp.v.x = verts[k][0];
+ tmp.v.y = verts[k][1];
+ tmp.v.u0 = texcoords[k][0];
+ tmp.v.v0 = texcoords[k][1];
+
+ for (i = 0 ; i < vertex_size ; i++)
+ vb[i] = tmp.ui[i];
+
+ vb += vertex_size;
+ }
+}
+
+static void
+I915UpdateRotate (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn1 = pScrn;
+ I830Ptr pI8301 = NULL;
+ RegionPtr damage = shadowDamage(pBuf);
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ int box_x1, box_x2, box_y1, box_y2;
+ CARD32 vb[32]; /* 32 dword vertex buffer */
+ float verts[4][2], tex[4][2];
+ struct matrix23 rotMatrix;
+ int j;
+ int use_fence;
+ Bool updateInvarient = FALSE;
+#ifdef XF86DRI
+ drmI830Sarea *sarea = NULL;
+ drm_context_t myContext = 0;
+#endif
+ Bool didLock = FALSE;
+
+ if (I830IsPrimary(pScrn)) {
+ pI8301 = pI830;
+ } else {
+ pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pScrn1 = pI830->entityPrivate->pScrn_1;
+ }
+
+ switch (pI830->rotation) {
+ case RR_Rotate_90:
+ matrix23Rotate(&rotMatrix,
+ pScreen->width, pScreen->height,
+ 90);
+ break;
+ case RR_Rotate_180:
+ matrix23Rotate(&rotMatrix,
+ pScreen->width, pScreen->height,
+ 180);
+ break;
+ case RR_Rotate_270:
+ matrix23Rotate(&rotMatrix,
+ pScreen->width, pScreen->height,
+ 270);
+ break;
+ default:
+ break;
+ }
+
+#ifdef XF86DRI
+ if (pI8301->directRenderingEnabled) {
+ sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
+ myContext = DRIGetContext(pScrn1->pScreen);
+ didLock = I830DRILock(pScrn1);
+ }
+#endif
+
+ if (pScrn->scrnIndex != *pI830->used3D)
+ updateInvarient = TRUE;
+
+#ifdef XF86DRI
+ if (sarea->ctxOwner != myContext)
+ updateInvarient = TRUE;
+#endif
+
+ if (updateInvarient) {
+ *pI830->used3D = pScrn->scrnIndex;
+#ifdef XF86DRI
+ if (sarea)
+ sarea->ctxOwner = myContext;
+#endif
+ BEGIN_LP_RING(64);
+ /* invarient state */
+ OUT_RING(MI_NOOP);
+ OUT_RING(0x66014140);
+ OUT_RING(0x7d990000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x7d9a0000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x7d980000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x76fac688);
+ OUT_RING(0x6700a770);
+ OUT_RING(0x7d040081);
+ OUT_RING(0x00000000);
+ /* flush map & render cache */
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(0x00000000);
+ /* draw rect */
+ OUT_RING(0x7d800003);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ /* scissor */
+ OUT_RING(0x7c800002);
+ OUT_RING(0x7d810001);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x7c000003);
+ OUT_RING(0x7d070000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x68000002);
+ /* context setup */
+ OUT_RING(0x6db3ffff);
+ OUT_RING(0x7d040744);
+ OUT_RING(0xfffffff0);
+ OUT_RING(0x00902c80);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00020216);
+ OUT_RING(0x6ba008a1);
+ OUT_RING(0x7d880000);
+ OUT_RING(0x00000000);
+ /* dv0 */
+ OUT_RING(0x7d850000);
+ /* dv1 */
+ if (pI830->cpp == 1)
+ OUT_RING(0x10880000);
+ else if (pI830->cpp == 2)
+ OUT_RING(0x10880200);
+ else
+ OUT_RING(0x10880308);
+ /* stipple */
+ OUT_RING(0x7d830000);
+ OUT_RING(0x00000000);
+ /* fragment program - texture blend replace*/
+ OUT_RING(0x7d050008);
+ OUT_RING(0x19180000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x19083c00);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x15200000);
+ OUT_RING(0x01000000);
+ OUT_RING(0x00000000);
+ /* texture sampler state */
+ OUT_RING(0x7d010003);
+ OUT_RING(0x00000001);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ /* front buffer, pitch, offset */
+ OUT_RING(0x7d8e0001);
+ OUT_RING(0x03800000 | (((pI830->displayWidth * pI830->cpp) / 4) << 2));
+ if (I830IsPrimary(pScrn))
+ OUT_RING(pI830->FrontBuffer.Start);
+ else
+ OUT_RING(pI8301->FrontBuffer2.Start);
+
+ /* Set the entire frontbuffer up as a texture */
+ OUT_RING(0x7d000003);
+ OUT_RING(0x00000001);
+
+ if (I830IsPrimary(pScrn))
+ OUT_RING(pI830->RotatedMem.Start);
+ else
+ OUT_RING(pI8301->RotatedMem2.Start);
+
+ if (pI830->disableTiling)
+ use_fence = 0;
+ else
+ use_fence = 4;
+
+ if (pI830->cpp == 1)
+ use_fence |= 0x80; /* MAPSURF_8BIT */
+ else
+ if (pI830->cpp == 2)
+ use_fence |= 0x100; /* MAPSURF_16BIT */
+ else
+ use_fence |= 0x180; /* MAPSURF_32BIT */
+ OUT_RING(use_fence | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
+ OUT_RING(((((pScrn->displayWidth * pI830->cpp) / 4) - 1) << 21));
+ ADVANCE_LP_RING();
+ }
+
+ {
+ BEGIN_LP_RING(2);
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(0x00000000);
+ ADVANCE_LP_RING();
+ }
+
+ while (nbox--)
+ {
+ box_x1 = pbox->x1;
+ box_y1 = pbox->y1;
+ box_x2 = pbox->x2;
+ box_y2 = pbox->y2;
+ pbox++;
+
+ BEGIN_LP_RING(40);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+
+ /* vertex data */
+ OUT_RING(0x7f0c001f);
+ verts[0][0] = box_x1; verts[0][1] = box_y1;
+ verts[1][0] = box_x2; verts[1][1] = box_y1;
+ verts[2][0] = box_x2; verts[2][1] = box_y2;
+ verts[3][0] = box_x1; verts[3][1] = box_y2;
+ tex[0][0] = box_x1; tex[0][1] = box_y1;
+ tex[1][0] = box_x2; tex[1][1] = box_y1;
+ tex[2][0] = box_x2; tex[2][1] = box_y2;
+ tex[3][0] = box_x1; tex[3][1] = box_y2;
+
+ /* transform coordinates to rotated versions, but leave texcoords unchanged */
+ for (j = 0; j < 4; j++)
+ matrix23TransformCoordf(&rotMatrix, &verts[j][0], &verts[j][1]);
+
+ /* emit vertex buffer */
+ draw_poly(vb, verts, tex);
+ for (j = 0; j < 32; j++)
+ OUT_RING(vb[j]);
+
+ ADVANCE_LP_RING();
+ }
+
+#ifdef XF86DRI
+ if (didLock)
+ I830DRIUnlock(pScrn1);
+#endif
+}
+
+static void
+I830UpdateRotate (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830Ptr pI8301 = NULL;
+ ScrnInfoPtr pScrn1 = pScrn;
+ RegionPtr damage = shadowDamage(pBuf);
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ int box_x1, box_x2, box_y1, box_y2;
+ CARD32 vb[32]; /* 32 dword vertex buffer */
+ float verts[4][2], tex[4][2];
+ struct matrix23 rotMatrix;
+ Bool updateInvarient = FALSE;
+ int use_fence;
+ int j;
+#ifdef XF86DRI
+ drmI830Sarea *sarea = NULL;
+ drm_context_t myContext = 0;
+#endif
+ Bool didLock = FALSE;
+
+ if (I830IsPrimary(pScrn)) {
+ pI8301 = pI830;
+ } else {
+ pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pScrn1 = pI830->entityPrivate->pScrn_1;
+ }
+
+ switch (pI830->rotation) {
+ case RR_Rotate_90:
+ matrix23Rotate(&rotMatrix,
+ pScreen->width, pScreen->height,
+ 90);
+ break;
+ case RR_Rotate_180:
+ matrix23Rotate(&rotMatrix,
+ pScreen->width, pScreen->height,
+ 180);
+ break;
+ case RR_Rotate_270:
+ matrix23Rotate(&rotMatrix,
+ pScreen->width, pScreen->height,
+ 270);
+ break;
+ default:
+ break;
+ }
+
+#ifdef XF86DRI
+ if (pI8301->directRenderingEnabled) {
+ sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
+ myContext = DRIGetContext(pScrn1->pScreen);
+ didLock = I830DRILock(pScrn1);
+ }
+#endif
+
+ if (pScrn->scrnIndex != *pI830->used3D)
+ updateInvarient = TRUE;
+
+#ifdef XF86DRI
+ if (sarea->ctxOwner != myContext)
+ updateInvarient = TRUE;
+#endif
+
+ if (updateInvarient) {
+ *pI830->used3D = pScrn->scrnIndex;
+#ifdef XF86DRI
+ if (sarea)
+ sarea->ctxOwner = myContext;
+#endif
+
+ BEGIN_LP_RING(48);
+ OUT_RING(0x682008a1);
+ OUT_RING(0x6f402100);
+ OUT_RING(0x62120aa9);
+ OUT_RING(0x76b3ffff);
+ OUT_RING(0x6c818a01);
+ OUT_RING(0x6ba008a1);
+ OUT_RING(0x69802100);
+ OUT_RING(0x63a00aaa);
+ OUT_RING(0x6423070e);
+ OUT_RING(0x66014142);
+ OUT_RING(0x75000000);
+ OUT_RING(0x7d880000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x650001c4);
+ OUT_RING(0x6a000000);
+ OUT_RING(0x7d020000);
+ OUT_RING(0x0000ba98);
+
+ /* flush map & render cache */
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(0x00000000);
+ /* draw rect */
+ OUT_RING(0x7d800003);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+
+ /* front buffer */
+ OUT_RING(0x7d8e0001);
+ OUT_RING(0x03800000 | (((pI830->displayWidth * pI830->cpp) / 4) << 2));
+ if (I830IsPrimary(pScrn))
+ OUT_RING(pI830->FrontBuffer.Start);
+ else
+ OUT_RING(pI8301->FrontBuffer2.Start);
+ OUT_RING(0x7d850000);
+ if (pI830->cpp == 1)
+ OUT_RING(0x00880000);
+ else
+ if (pI830->cpp == 2)
+ OUT_RING(0x00880200);
+ else
+ OUT_RING(0x00880308);
+ /* scissor */
+ OUT_RING(0x7c800002);
+ OUT_RING(0x7d810001);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ /* stipple */
+ OUT_RING(0x7d830000);
+ OUT_RING(0x00000000);
+
+ /* texture blend replace */
+ OUT_RING(0x7c088088);
+ OUT_RING(0x00000000);
+ OUT_RING(0x6d021181);
+ OUT_RING(0x6d060101);
+ OUT_RING(0x6e008046);
+ OUT_RING(0x6e048046);
+
+
+ /* Set the entire frontbuffer up as a texture */
+ OUT_RING(0x7d030804);
+
+ if (pI830->disableTiling)
+ use_fence = 0;
+ else
+ use_fence = 2;
+
+ if (I830IsPrimary(pScrn))
+ OUT_RING(pI830->RotatedMem.Start | use_fence);
+ else
+ OUT_RING(pI8301->RotatedMem2.Start | use_fence);
+
+ if (pI830->cpp == 1)
+ OUT_RING(0x00 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
+ else if (pI830->cpp == 2)
+ OUT_RING(0x40 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
+ else
+ OUT_RING(0xc0 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
+
+ OUT_RING((((pScrn->displayWidth * pI830->cpp / 4) - 1) << 21));
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+
+
+ ADVANCE_LP_RING();
+ }
+
+ {
+ BEGIN_LP_RING(2);
+ /* flush map & render cache */
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(0x00000000);
+ ADVANCE_LP_RING();
+ }
+
+ while (nbox--)
+ {
+ box_x1 = pbox->x1;
+ box_y1 = pbox->y1;
+ box_x2 = pbox->x2;
+ box_y2 = pbox->y2;
+ pbox++;
+
+ BEGIN_LP_RING(40);
+
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+
+ /* vertex data */
+ OUT_RING(0x7f0c001f);
+ verts[0][0] = box_x1; verts[0][1] = box_y1;
+ verts[1][0] = box_x2; verts[1][1] = box_y1;
+ verts[2][0] = box_x2; verts[2][1] = box_y2;
+ verts[3][0] = box_x1; verts[3][1] = box_y2;
+ tex[0][0] = box_x1; tex[0][1] = box_y1;
+ tex[1][0] = box_x2; tex[1][1] = box_y1;
+ tex[2][0] = box_x2; tex[2][1] = box_y2;
+ tex[3][0] = box_x1; tex[3][1] = box_y2;
+
+ /* transform coordinates to rotated versions, but leave texcoords unchanged */
+ for (j = 0; j < 4; j++)
+ matrix23TransformCoordf(&rotMatrix, &verts[j][0], &verts[j][1]);
+
+ /* emit vertex buffer */
+ draw_poly(vb, verts, tex);
+ for (j = 0; j < 32; j++)
+ OUT_RING(vb[j]);
+
+ OUT_RING(0x05000000);
+ OUT_RING(0x00000000);
+
+ ADVANCE_LP_RING();
+ }
+
+ {
+ BEGIN_LP_RING(2);
+ /* flush map & render cache */
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(0x00000000);
+ ADVANCE_LP_RING();
+ }
+
+#ifdef XF86DRI
+ if (didLock)
+ I830DRIUnlock(pScrn1);
+#endif
+}
+
+Bool
+I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830Ptr pI8301 = NULL;
+ I830Ptr pI8302 = NULL;
+ ScrnInfoPtr pScrn1 = NULL;
+ ScrnInfoPtr pScrn2 = NULL;
+ int i;
+ ShadowUpdateProc func = NULL;
+ Rotation oldRotation = pI830->rotation; /* save old state */
+ int displayWidth = pScrn->displayWidth; /* save displayWidth */
+ Bool reAllocate = TRUE;
+ Bool didLock = FALSE;
+
+ /* Good pitches to allow tiling. Don't care about pitches < 1024. */
+ static const int pitches[] = {
+/*
+ 128 * 2,
+ 128 * 4,
+*/
+ 128 * 8,
+ 128 * 16,
+ 128 * 32,
+ 128 * 64,
+ 0
+ };
+
+ if (pI830->noAccel)
+ func = LoaderSymbol("shadowUpdateRotatePacked");
+ else
+ if (IS_I9XX(pI830))
+ func = I915UpdateRotate;
+ else
+ func = I830UpdateRotate;
+
+ if (I830IsPrimary(pScrn)) {
+ pI8301 = pI830;
+ pScrn1 = pScrn;
+ if (pI830->entityPrivate) {
+ pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
+ pScrn2 = pI830->entityPrivate->pScrn_2;
+ }
+ } else {
+ pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pScrn1 = pI830->entityPrivate->pScrn_1;
+ pI8302 = pI830;
+ pScrn2 = pScrn;
+ }
+
+ pI830->rotation = I830GetRotation(pScrn->pScreen);
+
+ /* Check if we've still got the same orientation, or same mode */
+ if (pI830->rotation == oldRotation && pI830->currentMode == mode)
+#if 0
+ reAllocate = FALSE;
+#else
+ return TRUE;
+#endif
+
+ /*
+ * We grab the DRI lock when reallocating buffers to avoid DRI clients
+ * getting bogus information.
+ */
+#ifdef XF86DRI
+ if (pI8301->directRenderingEnabled && reAllocate) {
+ didLock = I830DRILock(pScrn1);
+
+ /* Do heap teardown here
+ */
+ {
+ drmI830MemDestroyHeap destroy;
+ destroy.region = I830_MEM_REGION_AGP;
+
+ if (drmCommandWrite(pI8301->drmSubFD,
+ DRM_I830_DESTROY_HEAP,
+ &destroy, sizeof(destroy))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] I830 destroy heap failed\n");
+ }
+ }
+
+ if (pI8301->TexMem.Key != -1)
+ xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key);
+ I830FreeVidMem(pScrn1, &(pI8301->TexMem));
+ if (pI8301->StolenPool.Allocated.Key != -1) {
+ xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
+ xf86DeallocateGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
+ }
+ if (pI8301->DepthBuffer.Key != -1)
+ xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key);
+ I830FreeVidMem(pScrn1, &(pI8301->DepthBuffer));
+ if (pI8301->BackBuffer.Key != -1)
+ xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key);
+ I830FreeVidMem(pScrn1, &(pI8301->BackBuffer));
+ }
+#endif
+
+ if (reAllocate) {
+ *pI830->used3D |= 1<<31; /* use high bit to denote new rotation occured */
+
+ if (pI8301->RotatedMem.Key != -1)
+ xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
+
+ I830FreeVidMem(pScrn1, &(pI8301->RotatedMem));
+ memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
+ pI8301->RotatedMem.Key = -1;
+
+ if (pI830->entityPrivate) {
+ if (pI8301->RotatedMem2.Key != -1)
+ xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key);
+
+ I830FreeVidMem(pScrn1, &(pI8301->RotatedMem2));
+ memset(&(pI8301->RotatedMem2), 0, sizeof(pI8301->RotatedMem2));
+ pI8301->RotatedMem2.Key = -1;
+ }
+ }
+
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ if (reAllocate)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Rotating Screen to 0 degrees\n");
+ pScrn->displayWidth = pI830->displayWidth;
+ break;
+ case RR_Rotate_90:
+ if (reAllocate)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Rotating Screen to 90 degrees\n");
+ pScrn->displayWidth = pScrn->pScreen->width;
+ break;
+ case RR_Rotate_180:
+ if (reAllocate)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Rotating Screen to 180 degrees\n");
+ pScrn->displayWidth = pI830->displayWidth;
+ break;
+ case RR_Rotate_270:
+ if (reAllocate)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Rotating Screen to 270 degrees\n");
+ pScrn->displayWidth = pScrn->pScreen->width;
+ break;
+ }
+
+ /* As DRI doesn't run on the secondary head, we know that disableTiling
+ * is always TRUE.
+ */
+ if (I830IsPrimary(pScrn) && !pI830->disableTiling) {
+#if 0
+ int dWidth = pScrn->displayWidth; /* save current displayWidth */
+#endif
+
+ for (i = 0; pitches[i] != 0; i++) {
+ if (pitches[i] >= pScrn->displayWidth) {
+ pScrn->displayWidth = pitches[i];
+ break;
+ }
+ }
+
+ /*
+ * If the displayWidth is a tilable pitch, test if there's enough
+ * memory available to enable tiling.
+ */
+ if (pScrn->displayWidth == pitches[i]) {
+ /* TODO */
+ }
+ }
+
+ if (reAllocate) {
+ if (pI830->entityPrivate) {
+ if (pI8302->rotation != RR_Rotate_0) {
+ if (!I830AllocateRotated2Buffer(pScrn1,
+ pI8302->disableTiling ? ALLOC_NO_TILING : 0))
+ goto BAIL0;
+
+ I830FixOffset(pScrn1, &(pI8301->RotatedMem2));
+ if (pI8301->RotatedMem2.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
+ }
+ }
+
+ if (pI8301->rotation != RR_Rotate_0) {
+ if (!I830AllocateRotatedBuffer(pScrn1,
+ (pI8301->disableTiling ? ALLOC_NO_TILING : 0)))
+ goto BAIL1;
+
+ I830FixOffset(pScrn1, &(pI8301->RotatedMem));
+ if (pI8301->RotatedMem.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
+ }
+ }
+
+ shadowRemove (pScrn->pScreen, NULL);
+ if (pI830->rotation != RR_Rotate_0)
+ shadowAdd (pScrn->pScreen,
+ (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
+ func, I830WindowLinear, pI830->rotation, 0);
+
+ if (I830IsPrimary(pScrn)) {
+ if (pI830->rotation != RR_Rotate_0)
+ pScrn->fbOffset = pI830->RotatedMem.Start;
+ else
+ pScrn->fbOffset = pI830->FrontBuffer.Start;
+ if (pI830->entityPrivate) {
+ if (pI8302->rotation != RR_Rotate_0)
+ pScrn2->fbOffset = pI8301->RotatedMem2.Start;
+ else
+ pScrn2->fbOffset = pI8301->FrontBuffer2.Start;
+ I830SelectBuffer(pScrn2, I830_SELECT_FRONT);
+ }
+ } else {
+ if (pI830->rotation != RR_Rotate_0)
+ pScrn->fbOffset = pI8301->RotatedMem2.Start;
+ else
+ pScrn->fbOffset = pI8301->FrontBuffer2.Start;
+ if (pI8301->rotation != RR_Rotate_0)
+ pScrn1->fbOffset = pI8301->RotatedMem.Start;
+ else
+ pScrn1->fbOffset = pI8301->FrontBuffer.Start;
+ I830SelectBuffer(pScrn1, I830_SELECT_FRONT);
+ }
+ I830SelectBuffer(pScrn, I830_SELECT_FRONT);
+
+#ifdef XF86DRI
+ if (pI8301->directRenderingEnabled && reAllocate) {
+ if (!I830AllocateBackBuffer(pScrn1,
+ pI8301->disableTiling ? ALLOC_NO_TILING : 0))
+ goto BAIL2;
+
+ if (!I830AllocateDepthBuffer(pScrn1,
+ pI8301->disableTiling ? ALLOC_NO_TILING : 0))
+ goto BAIL3;
+
+ if (!I830AllocateTextureMemory(pScrn1,
+ pI8301->disableTiling ? ALLOC_NO_TILING : 0))
+ goto BAIL4;
+
+ I830DoPoolAllocation(pScrn1, &(pI8301->StolenPool));
+
+ I830FixOffset(pScrn1, &(pI8301->BackBuffer));
+ I830FixOffset(pScrn1, &(pI8301->DepthBuffer));
+
+ if (pI8301->BackBuffer.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
+ if (pI8301->DepthBuffer.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
+ if (pI8301->StolenPool.Allocated.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
+ if (pI8301->TexMem.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
+ I830SetupMemoryTiling(pScrn1);
+ /* update fence registers */
+ for (i = 0; i < 8; i++)
+ OUTREG(FENCE + i * 4, pI8301->ModeReg.Fence[i]);
+ {
+ drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
+ I830UpdateDRIBuffers(pScrn1, sarea );
+ }
+
+ if (didLock)
+ I830DRIUnlock(pScrn1);
+ }
+#endif
+
+#if 0
+ if (I830IsPrimary(pScrn)) {
+ pI830->xoffset = (pI830->FrontBuffer.Start / pI830->cpp) % pI830->displayWidth;
+ pI830->yoffset = (pI830->FrontBuffer.Start / pI830->cpp) / pI830->displayWidth;
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pI830->xoffset = (pI8301->FrontBuffer2.Start / pI830->cpp) % pI830->displayWidth;
+ pI830->yoffset = (pI8301->FrontBuffer2.Start / pI830->cpp) / pI830->displayWidth;
+ }
+#endif
+
+ pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen), pScrn->pScreen->width,
+ pScrn->pScreen->height, pScrn->pScreen->rootDepth, pScrn->bitsPerPixel,
+ PixmapBytePad(pScrn->displayWidth, pScrn->pScreen->rootDepth),
+ (pointer)(pI8301->FbBase + pScrn->fbOffset));
+
+ if (pI830->entityPrivate) {
+ if (I830IsPrimary(pScrn)) {
+ if (!pI830->starting) {
+ pScrn2->pScreen->ModifyPixmapHeader((*pScrn2->pScreen->GetScreenPixmap)(pScrn2->pScreen), pScrn2->pScreen->width,
+ pScrn2->pScreen->height, pScrn2->pScreen->rootDepth, pScrn2->bitsPerPixel,
+ PixmapBytePad(pScrn2->displayWidth, pScrn2->pScreen->rootDepth),
+ (pointer)(pI8301->FbBase + pScrn2->fbOffset));
+
+ /* Repaint the second head */
+ (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE);
+ (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE);
+ }
+ } else {
+ if (!pI830->starting) {
+ pScrn1->pScreen->ModifyPixmapHeader((*pScrn1->pScreen->GetScreenPixmap)(pScrn1->pScreen), pScrn1->pScreen->width,
+ pScrn1->pScreen->height, pScrn1->pScreen->rootDepth, pScrn1->bitsPerPixel,
+ PixmapBytePad(pScrn1->displayWidth, pScrn1->pScreen->rootDepth),
+ (pointer)(pI8301->FbBase + pScrn1->fbOffset));
+
+ /* Repaint the first head */
+ (*pScrn1->EnableDisableFBAccess) (pScrn1->pScreen->myNum, FALSE);
+ (*pScrn1->EnableDisableFBAccess) (pScrn1->pScreen->myNum, TRUE);
+ }
+ }
+ }
+
+ /* Don't allow pixmap cache or offscreen pixmaps when rotated */
+ /* XAA needs some serious fixing for this to happen */
+ if (pI830->rotation == RR_Rotate_0) {
+ pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
+ pI830->AccelInfoRec->UsingPixmapCache = TRUE;
+ /* funny as it seems this will enable XAA's createpixmap */
+ pI830->AccelInfoRec->maxOffPixWidth = 0;
+ pI830->AccelInfoRec->maxOffPixHeight = 0;
+ } else {
+ pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
+ pI830->AccelInfoRec->UsingPixmapCache = FALSE;
+ /* funny as it seems this will disable XAA's createpixmap */
+ pI830->AccelInfoRec->maxOffPixWidth = 1;
+ pI830->AccelInfoRec->maxOffPixHeight = 1;
+ }
+
+ return TRUE;
+
+BAIL4:
+#ifdef XF86DRI
+ if (pI8301->directRenderingEnabled)
+ I830FreeVidMem(pScrn1, &(pI8301->DepthBuffer));
+#endif
+BAIL3:
+#ifdef XF86DRI
+ if (pI8301->directRenderingEnabled)
+ I830FreeVidMem(pScrn1, &(pI8301->BackBuffer));
+#endif
+BAIL2:
+ if (pI8301->rotation != RR_Rotate_0) {
+ if (pI8301->RotatedMem.Key != -1)
+ xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
+
+ I830FreeVidMem(pScrn1, &(pI8301->RotatedMem));
+ memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
+ pI8301->RotatedMem.Key = -1;
+ }
+BAIL1:
+ if (pI830->entityPrivate) {
+ if (pI8302->rotation != RR_Rotate_0) {
+ if (pI8301->RotatedMem.Key != -1)
+ xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
+
+ I830FreeVidMem(pScrn1, &(pI8301->RotatedMem));
+ memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
+ pI8301->RotatedMem.Key = -1;
+ }
+ }
+BAIL0:
+ pScrn->displayWidth = displayWidth;
+
+ /* must flip mmWidth & mmHeight */
+ if ( ((oldRotation & (RR_Rotate_90 | RR_Rotate_270)) &&
+ (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))) ||
+ ((oldRotation & (RR_Rotate_0 | RR_Rotate_180)) &&
+ (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270))) ) {
+ int tmp = pScrn->pScreen->mmWidth;
+ pScrn->pScreen->mmWidth = pScrn->pScreen->mmHeight;
+ pScrn->pScreen->mmHeight = tmp;
+ }
+
+ if (oldRotation & (RR_Rotate_0 | RR_Rotate_180)) {
+ pScrn->pScreen->width = pScrn->virtualX;
+ pScrn->pScreen->height = pScrn->virtualY;
+ } else {
+ pScrn->pScreen->width = pScrn->virtualY;
+ pScrn->pScreen->height = pScrn->virtualX;
+ }
+
+ pI830->rotation = oldRotation;
+
+ if (pI830->entityPrivate) {
+ if (pI8302->rotation != RR_Rotate_0) {
+ if (!I830AllocateRotated2Buffer(pScrn1,
+ pI8302->disableTiling ? ALLOC_NO_TILING : 0))
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Oh dear, the rotated2 buffer failed - badness\n");
+
+ I830FixOffset(pScrn1, &(pI8301->RotatedMem2));
+ if (pI8301->RotatedMem2.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
+ }
+ }
+
+ if (pI8301->rotation != RR_Rotate_0) {
+ if (!I830AllocateRotatedBuffer(pScrn1,
+ (pI8301->disableTiling ? ALLOC_NO_TILING : 0)))
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Oh dear, the rotated buffer failed - badness\n");
+
+ I830FixOffset(pScrn1, &(pI8301->RotatedMem));
+ if (pI8301->RotatedMem.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
+ }
+
+ shadowRemove (pScrn->pScreen, NULL);
+ if (pI830->rotation != RR_Rotate_0)
+ shadowAdd (pScrn->pScreen,
+ (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
+ func, I830WindowLinear, pI830->rotation, 0);
+
+ if (I830IsPrimary(pScrn)) {
+ if (pI830->rotation != RR_Rotate_0)
+ pScrn->fbOffset = pI830->RotatedMem.Start;
+ else
+ pScrn->fbOffset = pI830->FrontBuffer.Start;
+ if (pI830->entityPrivate) {
+ if (pI8302->rotation != RR_Rotate_0)
+ pScrn2->fbOffset = pI8301->RotatedMem2.Start;
+ else
+ pScrn2->fbOffset = pI8301->FrontBuffer2.Start;
+ I830SelectBuffer(pScrn2, I830_SELECT_FRONT);
+ }
+ } else {
+ if (pI830->rotation != RR_Rotate_0)
+ pScrn->fbOffset = pI8301->RotatedMem2.Start;
+ else
+ pScrn->fbOffset = pI8301->FrontBuffer2.Start;
+ if (pI8301->rotation != RR_Rotate_0)
+ pScrn1->fbOffset = pI8301->RotatedMem.Start;
+ else
+ pScrn1->fbOffset = pI8301->FrontBuffer.Start;
+ I830SelectBuffer(pScrn1, I830_SELECT_FRONT);
+ }
+ I830SelectBuffer(pScrn, I830_SELECT_FRONT);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Reverting to previous configured mode\n");
+
+ switch (oldRotation) {
+ case RR_Rotate_0:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Rotating Screen back to 0 degrees\n");
+ break;
+ case RR_Rotate_90:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Rotating Screen back to 90 degrees\n");
+ break;
+ case RR_Rotate_180:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Rotating Screen back to 180 degrees\n");
+ break;
+ case RR_Rotate_270:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Rotating Screen back to 270 degrees\n");
+ break;
+ }
+
+#ifdef XF86DRI
+ if (pI8301->directRenderingEnabled) {
+ if (!I830AllocateBackBuffer(pScrn1,
+ pI8301->disableTiling ? ALLOC_NO_TILING : 0))
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Oh dear, the back buffer failed - badness\n");
+
+ if (!I830AllocateDepthBuffer(pScrn1,
+ pI8301->disableTiling ? ALLOC_NO_TILING : 0))
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Oh dear, the depth buffer failed - badness\n");
+
+ if (!I830AllocateTextureMemory(pScrn1,
+ pI8301->disableTiling ? ALLOC_NO_TILING : 0))
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Oh dear, the texture cache failed - badness\n");
+
+ I830DoPoolAllocation(pScrn1, &(pI8301->StolenPool));
+
+ I830FixOffset(pScrn1, &(pI8301->BackBuffer));
+ I830FixOffset(pScrn1, &(pI8301->DepthBuffer));
+
+ if (pI8301->BackBuffer.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
+ if (pI8301->DepthBuffer.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
+ if (pI8301->StolenPool.Allocated.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
+ if (pI8301->TexMem.Key != -1)
+ xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
+ I830SetupMemoryTiling(pScrn1);
+ /* update fence registers */
+ for (i = 0; i < 8; i++)
+ OUTREG(FENCE + i * 4, pI8301->ModeReg.Fence[i]);
+ {
+ drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
+ I830UpdateDRIBuffers(pScrn1, sarea );
+ }
+
+ if (didLock)
+ I830DRIUnlock(pScrn1);
+ }
+#endif
+
+ pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen), pScrn->pScreen->width,
+ pScrn->pScreen->height, pScrn->pScreen->rootDepth, pScrn->bitsPerPixel,
+ PixmapBytePad(pScrn->displayWidth, pScrn->pScreen->rootDepth),
+ (pointer)(pI8301->FbBase + pScrn->fbOffset));
+
+ if (pI830->entityPrivate) {
+ if (I830IsPrimary(pScrn)) {
+ pScrn2->pScreen->ModifyPixmapHeader((*pScrn2->pScreen->GetScreenPixmap)(pScrn2->pScreen), pScrn2->pScreen->width,
+ pScrn2->pScreen->height, pScrn2->pScreen->rootDepth, pScrn2->bitsPerPixel,
+ PixmapBytePad(pScrn2->displayWidth, pScrn2->pScreen->rootDepth),
+ (pointer)(pI8301->FbBase + pScrn2->fbOffset));
+
+ /* Repaint the second head */
+ (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE);
+ (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE);
+ } else {
+ pScrn1->pScreen->ModifyPixmapHeader((*pScrn1->pScreen->GetScreenPixmap)(pScrn1->pScreen), pScrn1->pScreen->width,
+ pScrn1->pScreen->height, pScrn1->pScreen->rootDepth, pScrn1->bitsPerPixel,
+ PixmapBytePad(pScrn1->displayWidth, pScrn1->pScreen->rootDepth),
+ (pointer)(pI8301->FbBase + pScrn1->fbOffset));
+
+ /* Repaint the first head */
+ (*pScrn1->EnableDisableFBAccess) (pScrn1->pScreen->myNum, FALSE);
+ (*pScrn1->EnableDisableFBAccess) (pScrn1->pScreen->myNum, TRUE);
+ }
+ }
+
+ return FALSE;
+}
diff --git a/src/i830_shadow.c b/src/i830_shadow.c
deleted file mode 100644
index 93c72c59..00000000
--- a/src/i830_shadow.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_shadow.c,v 1.3 2000/03/31 20:13:33 dawes Exp $ */
-
-/*
- Copyright (c) 1999,2000 The XFree86 Project Inc.
- based on code written by Mark Vojkovich <markv@valinux.com>
-*/
-
-/*
- * Ported from the savage driver to the I830 by
- * Helmar Spangenberg <hspangenberg@frey.de> and Dima Dorfman
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86.h"
-#include "i830.h"
-#include "shadowfb.h"
-#include "servermd.h"
-
-
-void
-I830RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- int width, height, Bpp, FBPitch;
- unsigned char *src, *dst;
-
- Bpp = pScrn->bitsPerPixel >> 3;
- FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
-
- while(num--) {
- width = (pbox->x2 - pbox->x1) * Bpp;
- height = pbox->y2 - pbox->y1;
- src = pI830->shadowPtr + (pbox->y1 * pI830->shadowPitch) +
- (pbox->x1 * Bpp);
- dst = pI830->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
-
- while(height--) {
- memcpy(dst, src, width);
- dst += FBPitch;
- src += pI830->shadowPitch;
- }
-
- pbox++;
- }
-}
-
-
-void
-I830PointerMoved(int index, int x, int y)
-{
- ScrnInfoPtr pScrn = xf86Screens[index];
- I830Ptr pI830 = I830PTR(pScrn);
- int newX, newY;
-
- if(pI830->rotate == 1) {
- newX = pScrn->pScreen->height - y - 1;
- newY = x;
- } else {
- newX = y;
- newY = pScrn->pScreen->width - x - 1;
- }
-
- (*pI830->PointerMoved)(index, newX, newY);
-}
-
-void
-I830RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- int count, width, height, y1, y2, dstPitch, srcPitch;
- CARD8 *dstPtr, *srcPtr, *src;
- CARD32 *dst;
-
- dstPitch = pScrn->displayWidth;
- srcPitch = -pI830->rotate * pI830->shadowPitch;
-
- while(num--) {
- width = pbox->x2 - pbox->x1;
- y1 = pbox->y1 & ~3;
- y2 = (pbox->y2 + 3) & ~3;
- height = (y2 - y1) >> 2; /* in dwords */
-
- if(pI830->rotate == 1) {
- dstPtr = pI830->FbBase +
- (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
- srcPtr = pI830->shadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
- } else {
- dstPtr = pI830->FbBase +
- ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
- srcPtr = pI830->shadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
- }
-
- while(width--) {
- src = srcPtr;
- dst = (CARD32*)dstPtr;
- count = height;
- while(count--) {
- *(dst++) = src[0] | (src[srcPitch] << 8) |
- (src[srcPitch * 2] << 16) |
- (src[srcPitch * 3] << 24);
- src += srcPitch * 4;
- }
- srcPtr += pI830->rotate;
- dstPtr += dstPitch;
- }
-
- pbox++;
- }
-}
-
-
-void
-I830RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- int count, width, height, y1, y2, dstPitch, srcPitch;
- CARD16 *dstPtr, *srcPtr, *src;
- CARD32 *dst;
-
- dstPitch = pScrn->displayWidth;
- srcPitch = -pI830->rotate * pI830->shadowPitch >> 1;
-
- while(num--) {
- width = pbox->x2 - pbox->x1;
- y1 = pbox->y1 & ~1;
- y2 = (pbox->y2 + 1) & ~1;
- height = (y2 - y1) >> 1; /* in dwords */
-
- if(pI830->rotate == 1) {
- dstPtr = (CARD16*)pI830->FbBase +
- (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
- srcPtr = (CARD16*)pI830->shadowPtr +
- ((1 - y2) * srcPitch) + pbox->x1;
- } else {
- dstPtr = (CARD16*)pI830->FbBase +
- ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
- srcPtr = (CARD16*)pI830->shadowPtr +
- (y1 * srcPitch) + pbox->x2 - 1;
- }
-
- while(width--) {
- src = srcPtr;
- dst = (CARD32*)dstPtr;
- count = height;
- while(count--) {
- *(dst++) = src[0] | (src[srcPitch] << 16);
- src += srcPitch * 2;
- }
- srcPtr += pI830->rotate;
- dstPtr += dstPitch;
- }
-
- pbox++;
- }
-}
-
-
-/* this one could be faster */
-void
-I830RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- int count, width, height, y1, y2, dstPitch, srcPitch;
- CARD8 *dstPtr, *srcPtr, *src;
- CARD32 *dst;
-
- dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
- srcPitch = -pI830->rotate * pI830->shadowPitch;
-
- while(num--) {
- width = pbox->x2 - pbox->x1;
- y1 = pbox->y1 & ~3;
- y2 = (pbox->y2 + 3) & ~3;
- height = (y2 - y1) >> 2; /* blocks of 3 dwords */
-
- if(pI830->rotate == 1) {
- dstPtr = pI830->FbBase +
- (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
- srcPtr = pI830->shadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
- } else {
- dstPtr = pI830->FbBase +
- ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
- srcPtr = pI830->shadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
- }
-
- while(width--) {
- src = srcPtr;
- dst = (CARD32*)dstPtr;
- count = height;
- while(count--) {
- dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
- (src[srcPitch] << 24);
- dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
- (src[srcPitch * 2] << 16) |
- (src[(srcPitch * 2) + 1] << 24);
- dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
- (src[(srcPitch * 3) + 1] << 16) |
- (src[(srcPitch * 3) + 2] << 24);
- dst += 3;
- src += srcPitch * 4;
- }
- srcPtr += pI830->rotate * 3;
- dstPtr += dstPitch;
- }
-
- pbox++;
- }
-}
-
-void
-I830RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- int count, width, height, dstPitch, srcPitch;
- CARD32 *dstPtr, *srcPtr, *src, *dst;
-
- dstPitch = pScrn->displayWidth;
- srcPitch = -pI830->rotate * pI830->shadowPitch >> 2;
-
- while(num--) {
- width = pbox->x2 - pbox->x1;
- height = pbox->y2 - pbox->y1;
-
- if(pI830->rotate == 1) {
- dstPtr = (CARD32*)pI830->FbBase +
- (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
- srcPtr = (CARD32*)pI830->shadowPtr +
- ((1 - pbox->y2) * srcPitch) + pbox->x1;
- } else {
- dstPtr = (CARD32*)pI830->FbBase +
- ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
- srcPtr = (CARD32*)pI830->shadowPtr +
- (pbox->y1 * srcPitch) + pbox->x2 - 1;
- }
-
- while(width--) {
- src = srcPtr;
- dst = dstPtr;
- count = height;
- while(count--) {
- *(dst++) = *src;
- src += srcPitch;
- }
- srcPtr += pI830->rotate;
- dstPtr += dstPitch;
- }
-
- pbox++;
- }
-}
diff --git a/src/i830_video.c b/src/i830_video.c
index 12c25e05..28e95be9 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -73,7 +73,7 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86Pci.h"
#include "xf86fbman.h"
#include "regionstr.h"
-
+#include "randrstr.h"
#include "i830.h"
#include "xf86xv.h"
#include <X11/extensions/Xv.h>
@@ -114,12 +114,13 @@ static void I830BlockHandler(int, pointer, pointer, pointer);
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
-static Atom xvBrightness, xvContrast, xvColorKey, xvPipe;
+static Atom xvBrightness, xvContrast, xvColorKey, xvPipe, xvDoubleBuffer;
static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
-#define IMAGE_MAX_WIDTH 1440
+#define IMAGE_MAX_WIDTH 1920
#define IMAGE_MAX_HEIGHT 1080
-#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT)
+#define IMAGE_MAX_WIDTH_LEGACY 1024
+#define IMAGE_MAX_HEIGHT_LEGACY 1080
#if !VIDEO_DEBUG
#define ErrorF Edummy
@@ -138,13 +139,13 @@ Edummy(const char *dummy, ...)
* all modes of server exit.
*/
-#define OVERLAY_UPDATE \
+#define OVERLAY_UPDATE \
do { \
BEGIN_LP_RING(6); \
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); \
OUT_RING(MI_NOOP); \
if (!*pI830->overlayOn) { \
- OUT_RING(MI_NOOP); \
+ OUT_RING(MI_NOOP); \
OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON); \
ErrorF("Overlay goes from off to on\n"); \
@@ -154,7 +155,7 @@ Edummy(const char *dummy, ...)
OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \
} \
- OUT_RING(pI830->OverlayMem->Physical | 1); \
+ OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
ADVANCE_LP_RING(); \
ErrorF("OVERLAY_UPDATE\n"); \
} while(0)
@@ -162,18 +163,28 @@ Edummy(const char *dummy, ...)
#define OVERLAY_OFF \
do { \
if (*pI830->overlayOn) { \
- BEGIN_LP_RING(8); \
+ int spin = 1000000; \
+ BEGIN_LP_RING(12); \
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); \
OUT_RING(MI_NOOP); \
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
+ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \
+ OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
+ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
+ OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF); \
- OUT_RING(pI830->OverlayMem->Physical); \
+ OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
ADVANCE_LP_RING(); \
*pI830->overlayOn = FALSE; \
ErrorF("Overlay goes from on to off\n"); \
+ while (spin != 0 && (INREG(OCMD_REGISTER) & OVERLAY_ENABLE)){ \
+ ErrorF("SPIN %d\n",spin); \
+ spin--; \
+ } \
+ if (spin == 0) ErrorF("OVERLAY FAILED TO GO OFF\n"); \
ErrorF("OVERLAY_OFF\n"); \
} \
} while(0)
@@ -181,6 +192,7 @@ Edummy(const char *dummy, ...)
/*
* OCMD - Overlay Command Register
*/
+#define OCMD_REGISTER 0x30168
#define MIRROR_MODE (0x3<<17)
#define MIRROR_HORIZONTAL (0x1<<17)
#define MIRROR_VERTICAL (0x2<<17)
@@ -212,11 +224,15 @@ Edummy(const char *dummy, ...)
#define FIELD1 (0x1<<1)
#define OVERLAY_ENABLE 0x1
+#define OFC_UPDATE 0x1
+
/* OCONFIG register */
#define CC_OUT_8BIT (0x1<<3)
#define OVERLAY_PIPE_MASK (0x1<<18)
#define OVERLAY_PIPE_A (0x0<<18)
#define OVERLAY_PIPE_B (0x1<<18)
+#define THREE_LINE_BUFFERS (0x1<<0)
+#define TWO_LINE_BUFFERS (0x0<<0)
/* DCLRKM register */
#define DEST_KEY_ENABLE (0x1<<31)
@@ -260,11 +276,12 @@ static XF86AttributeRec CloneAttributes[CLONE_ATTRIBUTES] = {
{XvSettable | XvGettable, 0, 1, "XV_PIPE"}
};
-#define NUM_ATTRIBUTES 3
+#define NUM_ATTRIBUTES 4
static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
{XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
- {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
+ {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
+ {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}
};
#define GAMMA_ATTRIBUTES 6
@@ -355,6 +372,7 @@ typedef struct {
int brightness;
int contrast;
int pipe;
+ int doubleBuffer;
RegionRec clip;
CARD32 colorKey;
@@ -390,7 +408,7 @@ CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
for (i = 0; i < size; i += 4) {
val = INREG(0x30100 + i);
if (val != overlay[i / 4]) {
- ErrorF("0x%05x value doesn't match (0x%08x != 0x%08x)\n",
+ ErrorF("0x%05x value doesn't match (0x%lx != 0x%lx)\n",
0x30100 + i, val, overlay[i / 4]);
bad++;
}
@@ -463,7 +481,7 @@ I830ResetVideo(ScrnInfoPtr pScrn)
I830OverlayRegPtr overlay =
(I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
- DPRINTF(PFX, "I830ResetVideo: base: %p, offset: 0x%08x, obase: %p\n",
+ DPRINTF(PFX, "I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n",
pI830->FbBase, pI830->OverlayMem->Start, overlay);
/*
* Default to maximum image size in YV12
@@ -475,10 +493,10 @@ I830ResetVideo(ScrnInfoPtr pScrn)
overlay->HORZ_PH = 0;
overlay->INIT_PHS = 0;
overlay->DWINPOS = 0;
- overlay->DWINSZ = (IMAGE_MAX_HEIGHT << 16) | IMAGE_MAX_WIDTH;
- overlay->SWIDTH = IMAGE_MAX_WIDTH | (IMAGE_MAX_WIDTH << 16);
- overlay->SWIDTHSW = (IMAGE_MAX_WIDTH >> 3) | (IMAGE_MAX_WIDTH << 12);
- overlay->SHEIGHT = IMAGE_MAX_HEIGHT | (IMAGE_MAX_HEIGHT << 15);
+ overlay->DWINSZ = 0;
+ overlay->SWIDTH = 0;
+ overlay->SWIDTHSW = 0;
+ overlay->SHEIGHT = 0;
overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
overlay->OCLRC1 = 0x00000080; /* saturation: bypass */
overlay->AWINPOS = 0;
@@ -532,7 +550,7 @@ I830ResetVideo(ScrnInfoPtr pScrn)
{
int i;
for (i = 0x30000; i < 0x31000; i += 4)
- ErrorF("0x%x 0x%08x\n", i, INREG(i));
+ ErrorF("0x%x 0x%lx\n", i, INREG(i));
}
#endif
}
@@ -602,10 +620,15 @@ I830SetupImageVideo(ScreenPtr pScreen)
return NULL;
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
- adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
adapt->name = "Intel(R) Video Overlay";
adapt->nEncodings = 1;
adapt->pEncodings = DummyEncoding;
+ /* update the DummyEncoding for these two chipsets */
+ if (IS_845G(pI830) || IS_I830(pI830)) {
+ adapt->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY;
+ adapt->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY;
+ }
adapt->nFormats = NUM_FORMATS;
adapt->pFormats = Formats;
adapt->nPorts = 1;
@@ -617,7 +640,7 @@ I830SetupImageVideo(ScreenPtr pScreen)
adapt->nAttributes = NUM_ATTRIBUTES;
if (pI830->Clone)
adapt->nAttributes += CLONE_ATTRIBUTES;
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
+ if (IS_I9XX(pI830))
adapt->nAttributes += GAMMA_ATTRIBUTES; /* has gamma */
adapt->pAttributes = xnfalloc(sizeof(XF86AttributeRec) * adapt->nAttributes);
/* Now copy the attributes */
@@ -628,7 +651,7 @@ I830SetupImageVideo(ScreenPtr pScreen)
memcpy((char*)att, (char*)CloneAttributes, sizeof(XF86AttributeRec) * CLONE_ATTRIBUTES);
att+=CLONE_ATTRIBUTES;
}
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
+ if (IS_I9XX(pI830)) {
memcpy((char*)att, (char*)GammaAttributes, sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES);
att+=GAMMA_ATTRIBUTES;
}
@@ -658,6 +681,7 @@ I830SetupImageVideo(ScreenPtr pScreen)
pPriv->gamma2 = 0x202020;
pPriv->gamma1 = 0x101010;
pPriv->gamma0 = 0x080808;
+ pPriv->doubleBuffer = 1;
/* gotta uninit this someplace */
REGION_NULL(pScreen, &pPriv->clip);
@@ -680,15 +704,16 @@ I830SetupImageVideo(ScreenPtr pScreen)
pI830->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = I830BlockHandler;
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
xvContrast = MAKE_ATOM("XV_CONTRAST");
- xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
/* Allow the pipe to be switched from pipe A to B when in clone mode */
if (pI830->Clone)
xvPipe = MAKE_ATOM("XV_PIPE");
-
- if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
+
+ if (IS_I9XX(pI830)) {
xvGamma0 = MAKE_ATOM("XV_GAMMA0");
xvGamma1 = MAKE_ATOM("XV_GAMMA1");
xvGamma2 = MAKE_ATOM("XV_GAMMA2");
@@ -747,10 +772,12 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
if (shutdown) {
if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
+
overlay->OCMD &= ~OVERLAY_ENABLE;
OVERLAY_UPDATE;
-
+#if 1
OVERLAY_OFF;
+#endif
if (pI830->entityPrivate)
pI830->entityPrivate->XvInUse = -1;
@@ -783,15 +810,23 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
return BadValue;
pPriv->brightness = value;
overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
- if (pPriv->overlayOK)
- OVERLAY_UPDATE;
+ ErrorF("BRIGHTNESS\n");
+ overlay->OCMD &= ~OVERLAY_ENABLE;
+ OVERLAY_UPDATE;
+#if 1
+ OVERLAY_OFF;
+#endif
} else if (attribute == xvContrast) {
if ((value < 0) || (value > 255))
return BadValue;
pPriv->contrast = value;
overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
- if (pPriv->overlayOK)
- OVERLAY_UPDATE;
+ ErrorF("CONTRAST\n");
+ overlay->OCMD &= ~OVERLAY_ENABLE;
+ OVERLAY_UPDATE;
+#if 1
+ OVERLAY_OFF;
+#endif
} else if (pI830->Clone && attribute == xvPipe) {
if ((value < 0) || (value > 1))
return BadValue;
@@ -804,52 +839,36 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
overlay->OCONFIG |= OVERLAY_PIPE_A;
else
overlay->OCONFIG |= OVERLAY_PIPE_B;
- if (pPriv->overlayOK)
- OVERLAY_UPDATE;
- } else if (attribute == xvGamma0 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
- /* Avoid video anomalies, so set gamma registers when overlay is off */
- /* We also clamp the values if they are outside the ranges */
- if (!*pI830->overlayOn) {
- pPriv->gamma0 = value;
- if (pPriv->gamma1 - pPriv->gamma0 > 0x7d)
- pPriv->gamma1 = pPriv->gamma0 + 0x7d;
- } else
- return BadRequest;
- } else if (attribute == xvGamma1 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
- if (!*pI830->overlayOn) {
- pPriv->gamma1 = value;
- if (pPriv->gamma1 - pPriv->gamma0 > 0x7d)
- pPriv->gamma0 = pPriv->gamma1 - 0x7d;
- } else
- return BadRequest;
- } else if (attribute == xvGamma2 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
- if (!*pI830->overlayOn) {
- pPriv->gamma2 = value;
- if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)
- pPriv->gamma3 = pPriv->gamma2 + 0x7d;
- } else
- return BadRequest;
- } else if (attribute == xvGamma3 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
- if (!*pI830->overlayOn) {
- pPriv->gamma3 = value;
- if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)
- pPriv->gamma2 = pPriv->gamma3 - 0x7d;
- } else
- return BadRequest;
- } else if (attribute == xvGamma4 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
- if (!*pI830->overlayOn) {
- pPriv->gamma4 = value;
- if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)
- pPriv->gamma5 = pPriv->gamma4 + 0x7d;
- } else
- return BadRequest;
- } else if (attribute == xvGamma5 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
- if (!*pI830->overlayOn) {
- pPriv->gamma5 = value;
- if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)
- pPriv->gamma4 = pPriv->gamma5 - 0x7d;
- } else
- return BadRequest;
+ ErrorF("PIPE CHANGE\n");
+ overlay->OCMD &= ~OVERLAY_ENABLE;
+ OVERLAY_UPDATE;
+#if 1
+ OVERLAY_OFF;
+#endif
+ } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
+ pPriv->gamma0 = value;
+ if (pPriv->gamma1 - pPriv->gamma0 > 0x7d)
+ pPriv->gamma1 = pPriv->gamma0 + 0x7d;
+ } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
+ pPriv->gamma1 = value;
+ if (pPriv->gamma1 - pPriv->gamma0 > 0x7d)
+ pPriv->gamma0 = pPriv->gamma1 - 0x7d;
+ } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) {
+ pPriv->gamma2 = value;
+ if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)
+ pPriv->gamma3 = pPriv->gamma2 + 0x7d;
+ } else if (attribute == xvGamma3 && (IS_I9XX(pI830))) {
+ pPriv->gamma3 = value;
+ if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)
+ pPriv->gamma2 = pPriv->gamma3 - 0x7d;
+ } else if (attribute == xvGamma4 && (IS_I9XX(pI830))) {
+ pPriv->gamma4 = value;
+ if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)
+ pPriv->gamma5 = pPriv->gamma4 + 0x7d;
+ } else if (attribute == xvGamma5 && (IS_I9XX(pI830))) {
+ pPriv->gamma5 = value;
+ if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)
+ pPriv->gamma4 = pPriv->gamma5 - 0x7d;
} else if (attribute == xvColorKey) {
pPriv->colorKey = value;
switch (pScrn->depth) {
@@ -863,9 +882,19 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
overlay->DCLRKV = pPriv->colorKey;
break;
}
- if (pPriv->overlayOK)
- OVERLAY_UPDATE;
+ ErrorF("COLORKEY\n");
+ overlay->OCMD &= ~OVERLAY_ENABLE;
+ OVERLAY_UPDATE;
+#if 1
+ OVERLAY_OFF;
+#endif
REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ } else if(attribute == xvDoubleBuffer) {
+ if ((value < 0) || (value > 1))
+ return BadValue;
+ /* Do not allow buffer change while playing video */
+ if(!*pI830->overlayOn)
+ pPriv->doubleBuffer = value;
} else
return BadMatch;
@@ -875,7 +904,13 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
attribute == xvGamma2 ||
attribute == xvGamma3 ||
attribute == xvGamma4 ||
- attribute == xvGamma5) && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
+ attribute == xvGamma5) && (IS_I9XX(pI830))) {
+ ErrorF("GAMMA\n");
+ overlay->OCMD &= ~OVERLAY_ENABLE;
+ OVERLAY_UPDATE;
+#if 1
+ OVERLAY_OFF;
+#endif
I830UpdateGamma(pScrn);
}
@@ -895,21 +930,23 @@ I830GetPortAttribute(ScrnInfoPtr pScrn,
*value = pPriv->contrast;
} else if (pI830->Clone && attribute == xvPipe) {
*value = pPriv->pipe;
- } else if (attribute == xvGamma0 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
+ } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
*value = pPriv->gamma0;
- } else if (attribute == xvGamma1 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
+ } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
*value = pPriv->gamma1;
- } else if (attribute == xvGamma2 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
+ } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) {
*value = pPriv->gamma2;
- } else if (attribute == xvGamma3 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
+ } else if (attribute == xvGamma3 && (IS_I9XX(pI830))) {
*value = pPriv->gamma3;
- } else if (attribute == xvGamma4 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
+ } else if (attribute == xvGamma4 && (IS_I9XX(pI830))) {
*value = pPriv->gamma4;
- } else if (attribute == xvGamma5 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
+ } else if (attribute == xvGamma5 && (IS_I9XX(pI830))) {
*value = pPriv->gamma5;
} else if (attribute == xvColorKey) {
*value = pPriv->colorKey;
- } else
+ } else if (attribute == xvDoubleBuffer) {
+ *value = pPriv->doubleBuffer;
+ } else
return BadMatch;
return Success;
@@ -940,8 +977,10 @@ I830CopyPackedData(ScrnInfoPtr pScrn,
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
unsigned char *src, *dst;
+ int i,j;
+ unsigned char *s;
- DPRINTF(PFX, "I830CopyPackedData: (%d,%d) (%d,%d)\n"
+ ErrorF("I830CopyPackedData: (%d,%d) (%d,%d)\n"
"srcPitch: %d, dstPitch: %d\n", top, left, h, w, srcPitch, dstPitch);
src = buf + (top * srcPitch) + (left << 1);
@@ -951,11 +990,76 @@ I830CopyPackedData(ScrnInfoPtr pScrn,
else
dst = pI830->FbBase + pPriv->YBuf1offset;
- w <<= 1;
- while (h--) {
- memcpy(dst, src, w);
- src += srcPitch;
- dst += dstPitch;
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ w <<= 1;
+ for (i = 0; i < h; i++) {
+ memcpy(dst, src, w);
+ src += srcPitch;
+ dst += dstPitch;
+ }
+ break;
+ case RR_Rotate_90:
+ h <<= 1;
+ for (i = 0; i < h; i+=2) {
+ s = src;
+ for (j = 0; j < w; j++) {
+ /* Copy Y */
+ dst[(i + 0) + ((w - j - 1) * dstPitch)] = *s++;
+ (void)*s++;
+ }
+ src += srcPitch;
+ }
+ h >>= 1;
+ src = buf + (top * srcPitch) + (left << 1);
+ for (i = 0; i < h; i+=2) {
+ for (j = 0; j < w; j+=2) {
+ /* Copy U */
+ dst[((i*2) + 1) + ((w - j - 1) * dstPitch)] = src[(j*2) + 1 + (i * srcPitch)];
+ dst[((i*2) + 1) + ((w - j - 2) * dstPitch)] = src[(j*2) + 1 + ((i+1) * srcPitch)];
+ /* Copy V */
+ dst[((i*2) + 3) + ((w - j - 1) * dstPitch)] = src[(j*2) + 3 + (i * srcPitch)];
+ dst[((i*2) + 3) + ((w - j - 2) * dstPitch)] = src[(j*2) + 3 + ((i+1) * srcPitch)];
+ }
+ }
+ break;
+ case RR_Rotate_180:
+ w <<= 1;
+ for (i = 0; i < h; i++) {
+ s = src;
+ for (j = 0; j < w; j+=4) {
+ dst[(w - j - 4) + ((h - i - 1) * dstPitch)] = *s++;
+ dst[(w - j - 3) + ((h - i - 1) * dstPitch)] = *s++;
+ dst[(w - j - 2) + ((h - i - 1) * dstPitch)] = *s++;
+ dst[(w - j - 1) + ((h - i - 1) * dstPitch)] = *s++;
+ }
+ src += srcPitch;
+ }
+ break;
+ case RR_Rotate_270:
+ h <<= 1;
+ for (i = 0; i < h; i+=2) {
+ s = src;
+ for (j = 0; j < w; j++) {
+ /* Copy Y */
+ dst[(h - i - 2) + (j * dstPitch)] = *s++;
+ (void)*s++;
+ }
+ src += srcPitch;
+ }
+ h >>= 1;
+ src = buf + (top * srcPitch) + (left << 1);
+ for (i = 0; i < h; i+=2) {
+ for (j = 0; j < w; j+=2) {
+ /* Copy U */
+ dst[(((h - i)*2) - 3) + (j * dstPitch)] = src[(j*2) + 1 + (i * srcPitch)];
+ dst[(((h - i)*2) - 3) + ((j - 1) * dstPitch)] = src[(j*2) + 1 + ((i+1) * srcPitch)];
+ /* Copy V */
+ dst[(((h - i)*2) - 1) + (j * dstPitch)] = src[(j*2) + 3 + (i * srcPitch)];
+ dst[(((h - i)*2) - 1) + ((j - 1) * dstPitch)] = src[(j*2) + 3 + ((i+1) * srcPitch)];
+ }
+ }
+ break;
}
}
@@ -966,8 +1070,10 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
{
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
- int i;
+ int i, j = 0;
unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;
+ unsigned char *s;
+ int dstPitch2 = dstPitch << 1;
ErrorF("I830CopyPlanarData: srcPitch %d, srcPitch %d, dstPitch %d\n"
"nlines %d, npixels %d, top %d, left %d\n", srcPitch, srcPitch2, dstPitch,
@@ -975,22 +1081,53 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
/* Copy Y data */
src1 = buf + (top * srcPitch) + left;
- ErrorF("src1 is %p, offset is %d\n", src1,
+ ErrorF("src1 is %p, offset is %ld\n", src1,
(unsigned long)src1 - (unsigned long)buf);
if (pPriv->currentBuf == 0)
dst1 = pI830->FbBase + pPriv->YBuf0offset;
else
dst1 = pI830->FbBase + pPriv->YBuf1offset;
- for (i = 0; i < h; i++) {
- memcpy(dst1, src1, w);
- src1 += srcPitch;
- dst1 += dstPitch << 1;
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ for (i = 0; i < h; i++) {
+ memcpy(dst1, src1, w);
+ src1 += srcPitch;
+ dst1 += dstPitch2;
+ }
+ break;
+ case RR_Rotate_90:
+ for (i = 0; i < h; i++) {
+ s = src1;
+ for (j = 0; j < w; j++) {
+ dst1[(i) + ((w - j - 1) * dstPitch2)] = *s++;
+ }
+ src1 += srcPitch;
+ }
+ break;
+ case RR_Rotate_180:
+ for (i = 0; i < h; i++) {
+ s = src1;
+ for (j = 0; j < w; j++) {
+ dst1[(w - j - 1) + ((h - i - 1) * dstPitch2)] = *s++;
+ }
+ src1 += srcPitch;
+ }
+ break;
+ case RR_Rotate_270:
+ for (i = 0; i < h; i++) {
+ s = src1;
+ for (j = 0; j < w; j++) {
+ dst1[(h - i - 1) + (j * dstPitch2)] = *s++;
+ }
+ src1 += srcPitch;
+ }
+ break;
}
/* Copy V data for YV12, or U data for I420 */
src2 = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
- ErrorF("src2 is %p, offset is %d\n", src2,
+ ErrorF("src2 is %p, offset is %ld\n", src2,
(unsigned long)src2 - (unsigned long)buf);
if (pPriv->currentBuf == 0) {
if (id == FOURCC_I420)
@@ -1004,16 +1141,47 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
dst2 = pI830->FbBase + pPriv->VBuf1offset;
}
- for (i = 0; i < h / 2; i++) {
- memcpy(dst2, src2, w / 2);
- src2 += srcPitch2;
- dst2 += dstPitch;
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ for (i = 0; i < h / 2; i++) {
+ memcpy(dst2, src2, w / 2);
+ src2 += srcPitch2;
+ dst2 += dstPitch;
+ }
+ break;
+ case RR_Rotate_90:
+ for (i = 0; i < (h/2); i++) {
+ s = src2;
+ for (j = 0; j < (w/2); j++) {
+ dst2[(i) + (((w/2) - j - 1) * (dstPitch))] = *s++;
+ }
+ src2 += srcPitch2;
+ }
+ break;
+ case RR_Rotate_180:
+ for (i = 0; i < (h/2); i++) {
+ s = src2;
+ for (j = 0; j < (w/2); j++) {
+ dst2[((w/2) - j - 1) + (((h/2) - i - 1) * dstPitch)] = *s++;
+ }
+ src2 += srcPitch2;
+ }
+ break;
+ case RR_Rotate_270:
+ for (i = 0; i < (h/2); i++) {
+ s = src2;
+ for (j = 0; j < (w/2); j++) {
+ dst2[((h/2) - i - 1) + (j * dstPitch)] = *s++;
+ }
+ src2 += srcPitch2;
+ }
+ break;
}
/* Copy U data for YV12, or V data for I420 */
src3 = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
((top * srcPitch) >> 2) + (left >> 1);
- ErrorF("src3 is %p, offset is %d\n", src3,
+ ErrorF("src3 is %p, offset is %ld\n", src3,
(unsigned long)src3 - (unsigned long)buf);
if (pPriv->currentBuf == 0) {
if (id == FOURCC_I420)
@@ -1027,10 +1195,41 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
dst3 = pI830->FbBase + pPriv->UBuf1offset;
}
- for (i = 0; i < h / 2; i++) {
- memcpy(dst3, src3, w / 2);
- src3 += srcPitch2;
- dst3 += dstPitch;
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ for (i = 0; i < h / 2; i++) {
+ memcpy(dst3, src3, w / 2);
+ src3 += srcPitch2;
+ dst3 += dstPitch;
+ }
+ break;
+ case RR_Rotate_90:
+ for (i = 0; i < (h/2); i++) {
+ s = src3;
+ for (j = 0; j < (w/2); j++) {
+ dst3[(i) + (((w/2) - j - 1) * (dstPitch))] = *s++;
+ }
+ src3 += srcPitch2;
+ }
+ break;
+ case RR_Rotate_180:
+ for (i = 0; i < (h/2); i++) {
+ s = src3;
+ for (j = 0; j < (w/2); j++) {
+ dst3[((w/2) - j - 1) + (((h/2) - i - 1) * dstPitch)] = *s++;
+ }
+ src3 += srcPitch2;
+ }
+ break;
+ case RR_Rotate_270:
+ for (i = 0; i < (h/2); i++) {
+ s = src3;
+ for (j = 0; j < (w/2); j++) {
+ dst3[((h/2) - i - 1) + (j * dstPitch)] = *s++;
+ }
+ src3 += srcPitch2;
+ }
+ break;
}
}
@@ -1175,6 +1374,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
(I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
unsigned int swidth;
unsigned int mask, shift, offsety, offsetu;
+ int tmp;
ErrorF("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
dstPitch);
@@ -1182,7 +1382,159 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
if (!pPriv->overlayOK)
return;
- if (IS_I915G(pI830) || IS_I915GM(pI830)) {
+#if VIDEO_DEBUG
+ CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
+#endif
+
+ /* When in dual head with different bpp setups we need to refresh the
+ * color key, so let's reset the video parameters and refresh here */
+#if 0
+ if (pI830->entityPrivate)
+#endif
+ I830ResetVideo(pScrn);
+
+ /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
+ if (!*pI830->overlayOn)
+ OVERLAY_UPDATE;
+
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ dstBox->x1 -= pScrn->frameX0;
+ dstBox->x2 -= pScrn->frameX0;
+ dstBox->y1 -= pScrn->frameY0;
+ dstBox->y2 -= pScrn->frameY0;
+ break;
+ case RR_Rotate_90:
+ tmp = dstBox->x1;
+ dstBox->x1 = dstBox->y1 - pScrn->frameX0;
+ dstBox->y1 = pScrn->virtualY - tmp - pScrn->frameY0;
+ tmp = dstBox->x2;
+ dstBox->x2 = dstBox->y2 - pScrn->frameX0;
+ dstBox->y2 = pScrn->virtualY - tmp - pScrn->frameY0;
+ tmp = dstBox->y1;
+ dstBox->y1 = dstBox->y2;
+ dstBox->y2 = tmp;
+ break;
+ case RR_Rotate_180:
+ tmp = dstBox->x1;
+ dstBox->x1 = pScrn->virtualX - dstBox->x2 - pScrn->frameX0;
+ dstBox->x2 = pScrn->virtualX - tmp - pScrn->frameX0;
+ tmp = dstBox->y1;
+ dstBox->y1 = pScrn->virtualY - dstBox->y2 - pScrn->frameY0;
+ dstBox->y2 = pScrn->virtualY - tmp - pScrn->frameY0;
+ break;
+ case RR_Rotate_270:
+ tmp = dstBox->x1;
+ dstBox->x1 = pScrn->virtualX - dstBox->y1 - pScrn->frameX0;
+ dstBox->y1 = tmp - pScrn->frameY0;
+ tmp = dstBox->x2;
+ dstBox->x2 = pScrn->virtualX - dstBox->y2 - pScrn->frameX0;
+ dstBox->y2 = tmp - pScrn->frameY0;
+ tmp = dstBox->x1;
+ dstBox->x1 = dstBox->x2;
+ dstBox->x2 = tmp;
+ break;
+ }
+
+ /* Fix up the dstBox if outside the visible screen */
+ {
+ int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0;
+ int offset_y = (dstBox->y1 < 0) ? -dstBox->y1 : 0;
+ int offset, offset2;
+
+ /* align */
+ offset_x = (offset_x + 3) & ~3;
+ offset_y = (offset_y + 3) & ~3;
+
+ if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ height -= offset_x;
+ width -= offset_y;
+ } else {
+ height -= offset_y;
+ width -= offset_x;
+ }
+
+ if (id == FOURCC_I420 || id == FOURCC_YV12) {
+ offset = ((offset_x/2) + (dstPitch * offset_y)) * 2;
+ offset2 = ((offset_x/2) + ((dstPitch/2) * offset_y));
+ } else {
+ offset = ((offset_x*2) + (dstPitch * offset_y));
+ offset2 = ((offset_x*2) + ((dstPitch/2) * offset_y));
+ }
+
+ /* buffer locations */
+ pPriv->YBuf0offset += offset;
+ pPriv->UBuf0offset += offset2;
+ pPriv->VBuf0offset += offset2;
+
+ if(pPriv->doubleBuffer) {
+ pPriv->YBuf1offset += offset;
+ pPriv->UBuf1offset += offset2;
+ pPriv->VBuf1offset += offset2;
+ }
+ }
+
+ if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ tmp = width;
+ width = height;
+ height = tmp;
+ tmp = drw_w;
+ drw_w = drw_h;
+ drw_h = tmp;
+ tmp = src_w;
+ src_w = src_h;
+ src_h = tmp;
+ }
+
+ if (pPriv->oneLineMode) {
+ /* change the coordinates with panel fitting active */
+ dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1;
+ dstBox->y2 = ((dstBox->y2 * pPriv->scaleRatio) >> 16) + 1;
+
+ /* Now, alter the height, so we scale to the correct size */
+ drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1;
+ }
+
+ {
+ /* Keep the engine happy and clip to the real vertical size just
+ * in case an LFP is in use and it's not at it's native resolution.
+ */
+ int vactive = pI830->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
+
+ vactive += 1;
+
+ if (dstBox->y1 < 0) dstBox->y1 = 0;
+ if (dstBox->y2 < 0) dstBox->y2 = 0;
+ if (dstBox->x1 < 0) dstBox->x1 = 0;
+ if (dstBox->x2 < 0) dstBox->x2 = 0;
+ if (dstBox->y1 > vactive) dstBox->y1 = vactive;
+ if (dstBox->y2 > vactive) dstBox->y2 = vactive;
+ if (dstBox->x1 > pScrn->currentMode->HDisplay) dstBox->x1 = pScrn->currentMode->HDisplay - 1;
+ if (dstBox->x2 > pScrn->currentMode->HDisplay) dstBox->x2 = pScrn->currentMode->HDisplay - 1;
+
+ /* nothing do to */
+ if ((!dstBox->x1 && !dstBox->x2) || (!dstBox->y1 && !dstBox->y2)) {
+ ErrorF("NOTHING TO DO\n");
+ return;
+ }
+ if ((dstBox->x1 == (pScrn->currentMode->HDisplay - 1) &&
+ dstBox->x2 == (pScrn->currentMode->HDisplay - 1)) ||
+ (dstBox->y1 == vactive &&
+ dstBox->y2 == vactive)) {
+ ErrorF("NOTHING TO DO\n");
+ return;
+ }
+ if ((dstBox->y2 - dstBox->y1) <= N_VERT_Y_TAPS) {
+ ErrorF("NOTHING TO DO\n");
+ return;
+ }
+ if ((dstBox->x2 - dstBox->x1) <= 2) {
+ ErrorF("NOTHING TO DO\n");
+ return;
+ }
+ }
+
+ if (IS_I9XX(pI830)) {
shift = 6;
mask = 0x3f;
} else {
@@ -1198,17 +1550,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
offsetu = pPriv->UBuf1offset;
}
-#if VIDEO_DEBUG
- CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
-#endif
-
- /* When in dual head with different bpp setups we need to refresh the
- * color key, so let's reset the video parameters and refresh here */
-#if 0
- if (pI830->entityPrivate)
-#endif
- I830ResetVideo(pScrn);
-
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
@@ -1221,7 +1562,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
swidth = ((offsety + width + mask) >> shift) -
(offsety >> shift);
- if (IS_I915G(pI830) || IS_I915GM(pI830))
+ if (IS_I9XX(pI830))
swidth <<= 1;
swidth -= 1;
@@ -1233,7 +1574,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
swidth = ((offsetu + (width / 2) + mask) >> shift) -
(offsetu >> shift);
- if (IS_I915G(pI830) || IS_I915GM(pI830))
+ if (IS_I9XX(pI830))
swidth <<= 1;
swidth -= 1;
@@ -1257,7 +1598,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
swidth = ((offsety + (width << 1) + mask) >> shift) -
(offsety >> shift);
- if (IS_I915G(pI830) || IS_I915GM(pI830))
+ if (IS_I9XX(pI830))
swidth <<= 1;
swidth -= 1;
@@ -1272,19 +1613,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
break;
}
- if (pPriv->oneLineMode) {
- /* change the coordinates with panel fitting active */
- dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1;
- dstBox->y2 = ((dstBox->y2 * pPriv->scaleRatio) >> 16) + 1;
-
- /* Now, alter the height, so we scale to the correct size */
- drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1;
-
- /* Keep the engine happy */
- if (dstBox->y1 < 0) dstBox->y1 = 0;
- if (dstBox->y2 < 0) dstBox->y2 = 0;
- }
-
+ overlay->OCMD = OVERLAY_ENABLE;
overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;
@@ -1299,13 +1628,15 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
overlay->OBUF_0U = pPriv->UBuf0offset;
overlay->OBUF_0V = pPriv->VBuf0offset;
- overlay->OBUF_1Y = pPriv->YBuf1offset;
- overlay->OBUF_1U = pPriv->UBuf1offset;
- overlay->OBUF_1V = pPriv->VBuf1offset;
+ if(pPriv->doubleBuffer) {
+ overlay->OBUF_1Y = pPriv->YBuf1offset;
+ overlay->OBUF_1U = pPriv->UBuf1offset;
+ overlay->OBUF_1V = pPriv->VBuf1offset;
+ }
- ErrorF("Buffers: Y0: 0x%08x, U0: 0x%08x, V0: 0x%08x\n", overlay->OBUF_0Y,
+ ErrorF("Buffers: Y0: 0x%lx, U0: 0x%lx, V0: 0x%lx\n", overlay->OBUF_0Y,
overlay->OBUF_0U, overlay->OBUF_0V);
- ErrorF("Buffers: Y1: 0x%08x, U1: 0x%08x, V1: 0x%08x\n", overlay->OBUF_1Y,
+ ErrorF("Buffers: Y1: 0x%lx, U1: 0x%lx, V1: 0x%lx\n", overlay->OBUF_1Y,
overlay->OBUF_1U, overlay->OBUF_1V);
#if 0
@@ -1330,11 +1661,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
}
#endif
-#if 1
- overlay->OCMD = OVERLAY_ENABLE;
-#endif
-
- ErrorF("pos: 0x%08x, size: 0x%08x\n", overlay->DWINPOS, overlay->DWINSZ);
+ ErrorF("pos: 0x%lx, size: 0x%lx\n", overlay->DWINPOS, overlay->DWINSZ);
ErrorF("dst: %d x %d, src: %d x %d\n", drw_w, drw_h, src_w, src_h);
/*
@@ -1383,6 +1710,18 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
ErrorF("UV xscale: %x.%03x, UV yscale: %x.%03x\n", xscaleIntUV,
xscaleFractUV & 0xFFF, yscaleIntUV, yscaleFractUV & 0xFFF);
+ /* shouldn't get here */
+ if (xscaleInt > 7) {
+ ErrorF("xscale: bad scale\n");
+ return;
+ }
+
+ /* shouldn't get here */
+ if (xscaleIntUV > 7) {
+ ErrorF("xscaleUV: bad scale\n");
+ return;
+ }
+
newval = (xscaleInt << 16) |
((xscaleFract & 0xFFF) << 3) | ((yscaleFract & 0xFFF) << 20);
if (newval != overlay->YRGBSCALE) {
@@ -1480,7 +1819,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
else
overlay->OCMD |= BUFFER1;
- ErrorF("OCMD is 0x%08x\n", overlay->OCMD);
+ ErrorF("OCMD is 0x%lx\n", overlay->OCMD);
OVERLAY_UPDATE;
}
@@ -1489,7 +1828,7 @@ static FBLinearPtr
I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
{
ScreenPtr pScreen;
- FBLinearPtr new_linear;
+ FBLinearPtr new_linear = NULL;
DPRINTF(PFX, "I830AllocateMemory\n");
@@ -1514,8 +1853,10 @@ I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4,
PRIORITY_EXTREME);
- if (max_size < size)
+ if (max_size < size) {
+ ErrorF("No memory available\n");
return NULL;
+ }
xf86PurgeUnlockedOffscreenAreas(pScreen);
new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4,
@@ -1538,6 +1879,8 @@ I830PutImage(ScrnInfoPtr pScrn,
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+ I830OverlayRegPtr overlay =
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
INT32 x1, x2, y1, y2;
int srcPitch, srcPitch2 = 0, dstPitch;
int top, left, npixels, nlines, size, loops;
@@ -1585,68 +1928,106 @@ I830PutImage(ScrnInfoPtr pScrn,
width, height))
return Success;
- dstBox.x1 -= pScrn->frameX0;
- dstBox.x2 -= pScrn->frameX0;
- dstBox.y1 -= pScrn->frameY0;
- dstBox.y2 -= pScrn->frameY0;
-
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
srcPitch = (width + 3) & ~3;
srcPitch2 = ((width >> 1) + 3) & ~3;
- dstPitch = ((width / 2) + 63) & ~63; /* of chroma */
- size = dstPitch * height * 3;
+#if 1
+ if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ dstPitch = ((height / 2) + 63) & ~63;
+ size = dstPitch * width * 3;
+ } else {
+ dstPitch = ((width / 2) + 63) & ~63; /* of chroma */
+ size = dstPitch * height * 3;
+ }
+#else
+ if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ dstPitch = ((height / 2) + 511) & ~511;
+ size = dstPitch * width * 3;
+ } else {
+ dstPitch = ((width / 2) + 511) & ~511; /* of chroma */
+ size = dstPitch * height * 3;
+ }
+#endif
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
srcPitch = width << 1;
- dstPitch = (srcPitch + 63) & ~63; /* of chroma */
- size = dstPitch * height;
+#if 1
+ if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ dstPitch = ((height << 1) + 63) & ~63;
+ size = dstPitch * width;
+ } else {
+ dstPitch = ((width << 1) + 63) & ~63; /* of chroma */
+ size = dstPitch * height;
+ }
+#else
+ if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ dstPitch = ((height << 1) + 511) & ~511;
+ size = dstPitch * width;
+ } else {
+ dstPitch = ((width << 1) + 511) & ~511; /* of chroma */
+ size = dstPitch * height;
+ }
+#endif
break;
}
ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
/* size is multiplied by 2 because we have two buffers that are flipping */
- if (!(pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear, size * 2 / pI830->cpp)))
+ pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear,
+ (pPriv->doubleBuffer ? size * 2 : size) / pI830->cpp);
+
+ if(!pPriv->linear || pPriv->linear->offset < (pScrn->virtualX * pScrn->virtualY))
return BadAlloc;
/* fixup pointers */
- pPriv->YBuf0offset = pScrn->fbOffset + pPriv->linear->offset * pI830->cpp;
- pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
- pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2);
-
- pPriv->YBuf1offset = pPriv->YBuf0offset + size;
- pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
- pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2);
-
- /* XXX We could potentially use MI_WAIT_FOR_OVERLAY here instead
- * of this code....*/
+ pPriv->YBuf0offset = pI830->FrontBuffer.Start + pPriv->linear->offset * pI830->cpp;
+ if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
+ pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
+ if(pPriv->doubleBuffer) {
+ pPriv->YBuf1offset = pPriv->YBuf0offset + size;
+ pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width);
+ pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2);
+ }
+ } else {
+ pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
+ pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2);
+ if(pPriv->doubleBuffer) {
+ pPriv->YBuf1offset = pPriv->YBuf0offset + size;
+ pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
+ pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2);
+ }
+ }
/* Make sure this buffer isn't in use */
loops = 0;
- while (loops < 1000000) {
+ if (*pI830->overlayOn && pPriv->doubleBuffer && (overlay->OCMD & OVERLAY_ENABLE)) {
+ while (loops < 1000000) {
#if USE_USLEEP_FOR_VIDEO
- usleep(10);
+ usleep(10);
#endif
- if (((INREG(DOVSTA) & OC_BUF) >> 20) == pPriv->currentBuf) {
- break;
+ if (((INREG(DOVSTA) & OC_BUF) >> 20) == pPriv->currentBuf) {
+ break;
+ }
+ loops++;
}
- loops++;
- }
- if (loops >= 1000000) {
- ErrorF("loops (1) maxed out for buffer %d\n", pPriv->currentBuf);
+ if (loops >= 1000000) {
+ ErrorF("loops (1) maxed out for buffer %d\n", pPriv->currentBuf);
#if 0
- pPriv->currentBuf = !pPriv->currentBuf;
+ pPriv->currentBuf = !pPriv->currentBuf;
#endif
- }
+ }
- /* buffer swap */
- if (pPriv->currentBuf == 0)
- pPriv->currentBuf = 1;
- else
- pPriv->currentBuf = 0;
+ /* buffer swap */
+ if (pPriv->currentBuf == 0)
+ pPriv->currentBuf = 1;
+ else
+ pPriv->currentBuf = 0;
+ }
/* copy data */
top = y1 >> 16;
@@ -1690,14 +2071,22 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn,
unsigned short *w, unsigned short *h,
int *pitches, int *offsets)
{
+ I830Ptr pI830 = I830PTR(pScrn);
int size, tmp;
- DPRINTF(PFX, "I830QueryImageAttributes: w is %d, h is %d\n", *w, *h);
+ ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h);
+ if (IS_845G(pI830) || IS_I830(pI830)) {
+ if (*w > IMAGE_MAX_WIDTH_LEGACY)
+ *w = IMAGE_MAX_WIDTH_LEGACY;
+ if (*h > IMAGE_MAX_HEIGHT_LEGACY)
+ *h = IMAGE_MAX_HEIGHT_LEGACY;
+ } else {
if (*w > IMAGE_MAX_WIDTH)
*w = IMAGE_MAX_WIDTH;
if (*h > IMAGE_MAX_HEIGHT)
*h = IMAGE_MAX_HEIGHT;
+ }
*w = (*w + 1) & ~1;
if (offsets)
@@ -1767,24 +2156,25 @@ I830BlockHandler(int i,
pScreen->BlockHandler = I830BlockHandler;
if (pPriv->videoStatus & TIMER_MASK) {
- UpdateCurrentTime();
+ Time now = currentTime.milliseconds;
if (pPriv->videoStatus & OFF_TIMER) {
- if (pPriv->offTime < currentTime.milliseconds) {
+ if (pPriv->offTime < now) {
/* Turn off the overlay */
+ ErrorF("BLOCKHANDLER\n");
overlay->OCMD &= ~OVERLAY_ENABLE;
-
- OVERLAY_UPDATE;
-
- OVERLAY_OFF;
+ OVERLAY_UPDATE;
+#if 1
+ OVERLAY_OFF;
+#endif
pPriv->videoStatus = FREE_TIMER;
- pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+ pPriv->freeTime = now + FREE_DELAY;
if (pI830->entityPrivate)
pI830->entityPrivate->XvInUse = -1;
}
} else { /* FREE_TIMER */
- if (pPriv->freeTime < currentTime.milliseconds) {
+ if (pPriv->freeTime < now) {
if (pPriv->linear) {
xf86FreeOffscreenLinear(pPriv->linear);
pPriv->linear = NULL;
@@ -1815,9 +2205,18 @@ I830AllocateSurface(ScrnInfoPtr pScrn,
OffscreenPrivPtr pPriv;
I830Ptr pI830 = I830PTR(pScrn);
- DPRINTF(PFX, "I830AllocateSurface\n");
+ ErrorF("I830AllocateSurface\n");
+
+ if (IS_845G(pI830) || IS_I830(pI830)) {
+ if ((w > IMAGE_MAX_WIDTH_LEGACY) || (h > IMAGE_MAX_HEIGHT_LEGACY))
+ return BadAlloc;
+ } else {
+ if ((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT))
+ return BadAlloc;
+ }
- if ((w > 1024) || (h > 1024))
+ /* What to do when rotated ?? */
+ if (pI830->rotation != RR_Rotate_0)
return BadAlloc;
w = (w + 1) & ~1;
@@ -1857,7 +2256,7 @@ I830AllocateSurface(ScrnInfoPtr pScrn,
surface->offsets[0] = linear->offset * bpp;
surface->devPrivate.ptr = (pointer) pPriv;
- memset(pI830->FbBase + pScrn->fbOffset + surface->offsets[0], 0, size);
+ memset(pI830->FbBase + pI830->FrontBuffer.Start + surface->offsets[0], 0, size);
return Success;
}
@@ -1874,11 +2273,12 @@ I830StopSurface(XF86SurfacePtr surface)
I830OverlayRegPtr overlay =
(I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
+ ErrorF("StopSurface\n");
overlay->OCMD &= ~OVERLAY_ENABLE;
-
OVERLAY_UPDATE;
-
+#if 1
OVERLAY_OFF;
+#endif
if (pI830->entityPrivate)
pI830->entityPrivate->XvInUse = -1;
@@ -1929,11 +2329,13 @@ I830DisplaySurface(XF86SurfacePtr surface,
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn);
+ I830OverlayRegPtr overlay =
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
INT32 x1, y1, x2, y2;
INT32 loops = 0;
BoxRec dstBox;
- DPRINTF(PFX, "I830DisplaySurface\n");
+ ErrorF("I830DisplaySurface\n");
if (pI830->entityPrivate) {
if (pI830->entityPrivate->XvInUse != -1 &&
@@ -1965,35 +2367,35 @@ I830DisplaySurface(XF86SurfacePtr surface,
surface->width, surface->height))
return Success;
- dstBox.x1 -= pScrn->frameX0;
- dstBox.x2 -= pScrn->frameX0;
- dstBox.y1 -= pScrn->frameY0;
- dstBox.y2 -= pScrn->frameY0;
-
/* fixup pointers */
pI830Priv->YBuf0offset = surface->offsets[0];
pI830Priv->YBuf1offset = pI830Priv->YBuf0offset;
- /* XXX We could potentially use MI_WAIT_FOR_OVERLAY here instead
- * of this code....*/
-
- /* wait for the last rendered buffer to be flipped in */
- while (((INREG(DOVSTA) & OC_BUF) >> 20) != pI830Priv->currentBuf) {
+ /* Make sure this buffer isn't in use */
+ loops = 0;
+ if (*pI830->overlayOn && pI830Priv->doubleBuffer && (overlay->OCMD & OVERLAY_ENABLE)) {
+ while (loops < 1000000) {
#if USE_USLEEP_FOR_VIDEO
- usleep(10);
+ usleep(10);
+#endif
+ if (((INREG(DOVSTA) & OC_BUF) >> 20) == pI830Priv->currentBuf) {
+ break;
+ }
+ loops++;
+ }
+ if (loops >= 1000000) {
+ ErrorF("loops (1) maxed out for buffer %d\n", pI830Priv->currentBuf);
+#if 0
+ pI830Priv->currentBuf = !pI830Priv->currentBuf;
#endif
- if (loops == 200000) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Overlay Lockup\n");
- break;
}
- loops++;
- }
- /* buffer swap */
- if (pI830Priv->currentBuf == 0)
- pI830Priv->currentBuf = 1;
- else
- pI830Priv->currentBuf = 0;
+ /* buffer swap */
+ if (pI830Priv->currentBuf == 0)
+ pI830Priv->currentBuf = 1;
+ else
+ pI830Priv->currentBuf = 0;
+ }
I830DisplayVideo(pScrn, surface->id, surface->width, surface->height,
surface->pitches[0], x1, y1, x2, y2, &dstBox,
@@ -2018,6 +2420,8 @@ static void
I830InitOffscreenImages(ScreenPtr pScreen)
{
XF86OffscreenImagePtr offscreenImages;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
/* need to free this someplace */
if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) {
@@ -2025,15 +2429,20 @@ I830InitOffscreenImages(ScreenPtr pScreen)
}
offscreenImages[0].image = &Images[0];
- offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
offscreenImages[0].alloc_surface = I830AllocateSurface;
offscreenImages[0].free_surface = I830FreeSurface;
offscreenImages[0].display = I830DisplaySurface;
offscreenImages[0].stop = I830StopSurface;
offscreenImages[0].setAttribute = I830SetSurfaceAttribute;
offscreenImages[0].getAttribute = I830GetSurfaceAttribute;
- offscreenImages[0].max_width = 1024;
- offscreenImages[0].max_height = 1024;
+ if (IS_845G(pI830) || IS_I830(pI830)) {
+ offscreenImages[0].max_width = IMAGE_MAX_WIDTH_LEGACY;
+ offscreenImages[0].max_height = IMAGE_MAX_HEIGHT_LEGACY;
+ } else {
+ offscreenImages[0].max_width = IMAGE_MAX_WIDTH;
+ offscreenImages[0].max_height = IMAGE_MAX_HEIGHT;
+ }
offscreenImages[0].num_attributes = 1;
offscreenImages[0].attributes = Attributes;
@@ -2043,9 +2452,10 @@ I830InitOffscreenImages(ScreenPtr pScreen)
void
I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
+ I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv;
- if (!I830PTR(pScrn)->adaptor) {
+ if (!pI830->adaptor) {
return;
}
@@ -2062,6 +2472,8 @@ I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode)
*/
I830StopVideo(pScrn, pPriv, TRUE);
+ pPriv->overlayOK = FALSE;
+
pPriv->oneLineMode = FALSE;
}
@@ -2079,6 +2491,17 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
if (!pPriv)
return;
+ pPriv->overlayOK = TRUE;
+
+ /* ensure pipe is updated on mode switch */
+ if (!pI830->Clone) {
+ if (pPriv->pipe != pI830->pipe) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Changing XVideo pipe (%d to %d).\n", pPriv->pipe, pI830->pipe);
+ pPriv->pipe = pI830->pipe;
+ }
+ }
+
if (pPriv->pipe == 0) {
if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,