xf86-video-intel: 24 commits - configure.ac man/intel.man src/i830.h src/i830_accel.c src/i830_common.h src/i830_display.c src/i830_dri.c src/i830_dri.h src/i830_driver.c src/i830_memory.c src/i830_xaa.c
Michel Daenzer
daenzer at kemper.freedesktop.org
Sat Mar 10 01:26:44 EET 2007
configure.ac | 5
man/intel.man | 20 +++
src/i830.h | 12 ++
src/i830_accel.c | 3
src/i830_common.h | 6 +
src/i830_display.c | 52 ++++++++
src/i830_dri.c | 309 +++++++++++++++++++++++++++++++++++++++++++----------
src/i830_dri.h | 4
src/i830_driver.c | 47 ++++++--
src/i830_memory.c | 47 +++++---
src/i830_xaa.c | 5
11 files changed, 428 insertions(+), 82 deletions(-)
New commits:
diff-tree 3c2d6e07bdf8daef6486b594aef0d22460eb2585 (from 7518b8959ee7598f3526365a83ea7e143a5d6a4e)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Fri Mar 9 23:49:46 2007 +0100
Don't crash when the SAREA pointer is NULL.
diff --git a/src/i830_display.c b/src/i830_display.c
index 7855712..d230f74 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -395,6 +395,9 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
if (pI830->directRenderingEnabled) {
drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen);
+ if (!sPriv)
+ return;
+
switch (pipe) {
case 0:
sPriv->pipeA_x = x;
@@ -516,6 +519,9 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen);
Bool enabled = crtc->enabled && mode != DPMSModeOff;
+ if (!sPriv)
+ return;
+
switch (pipe) {
case 0:
sPriv->pipeA_w = enabled ? crtc->mode.HDisplay : 0;
diff-tree 7518b8959ee7598f3526365a83ea7e143a5d6a4e (from 1991a90ae90b388c914985d20d6f8c3637856e9a)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Fri Mar 9 19:50:03 2007 +0100
Revert change accidentally included in previous commit.
diff --git a/src/i830_exa.c b/src/i830_exa.c
index dfc8f99..bef8fae 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -42,7 +42,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
#define DEBUG_I830FALLBACK 1
#endif
-#define ALWAYS_SYNC 0
+#define ALWAYS_SYNC 1
#ifdef DEBUG_I830FALLBACK
#define I830FALLBACK(s, arg...) \
diff-tree 1991a90ae90b388c914985d20d6f8c3637856e9a (from aef161853033907c6916337cebe88c8f111dd542)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Fri Mar 9 19:47:13 2007 +0100
Update SAREA pipe sizes in i830_crtc_dpms instead of i830PipeSetBase.
This allows setting the size to 0 when a pipe gets disabled.
diff --git a/src/i830_display.c b/src/i830_display.c
index 8a2494f..7855712 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -399,14 +399,10 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
case 0:
sPriv->pipeA_x = x;
sPriv->pipeA_y = y;
- sPriv->pipeA_w = crtc->mode.HDisplay;
- sPriv->pipeA_h = crtc->mode.VDisplay;
break;
case 1:
sPriv->pipeB_x = x;
sPriv->pipeB_y = y;
- sPriv->pipeB_w = crtc->mode.HDisplay;
- sPriv->pipeB_h = crtc->mode.VDisplay;
break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -514,6 +510,28 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
usleep(150);
break;
}
+
+#ifdef XF86DRI
+ if (pI830->directRenderingEnabled) {
+ drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen);
+ Bool enabled = crtc->enabled && mode != DPMSModeOff;
+
+ switch (pipe) {
+ case 0:
+ sPriv->pipeA_w = enabled ? crtc->mode.HDisplay : 0;
+ sPriv->pipeA_h = enabled ? crtc->mode.VDisplay : 0;
+ break;
+ case 1:
+ sPriv->pipeB_w = enabled ? crtc->mode.HDisplay : 0;
+ sPriv->pipeB_h = enabled ? crtc->mode.VDisplay : 0;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Can't update pipe %d in SAREA\n", pipe);
+ break;
+ }
+ }
+#endif
}
static Bool
diff --git a/src/i830_exa.c b/src/i830_exa.c
index bef8fae..dfc8f99 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -42,7 +42,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
#define DEBUG_I830FALLBACK 1
#endif
-#define ALWAYS_SYNC 1
+#define ALWAYS_SYNC 0
#ifdef DEBUG_I830FALLBACK
#define I830FALLBACK(s, arg...) \
diff-tree aef161853033907c6916337cebe88c8f111dd542 (from parents)
Merge: 1b54ee493fb96f944aa81e56fa6f00a8067f87fc 14ee9195d203192d3f613919f230b20b900ffdba
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Fri Mar 9 15:14:48 2007 +0100
Merge remote branch 'origin/master' into i830-pageflip
diff-tree 1b54ee493fb96f944aa81e56fa6f00a8067f87fc (from parents)
Merge: e972265261c421268e4fb806e587378d0adec577 81722a21d232fa6cfb11fbe3d984abab50e89bcc
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Fri Mar 9 15:13:50 2007 +0100
Merge remote branch 'origin/master' into i830-pageflip
Conflicts:
src/i830_dri.c
diff --cc src/i830_dri.c
index 9931acc,680a28e..5293574
@@@ -107,12 -107,7 +107,8 @@@
static void I830DRITransitionTo3d(ScreenPtr pScreen);
static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen);
static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen);
+static void I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num);
- #if 0
- static void I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
- #endif
-
extern void GlxSetVisualConfigs(int nconfigs,
__GLXvisualConfig * configs,
void **configprivs);
@@@ -1418,24 -1254,8 +1414,20 @@@
* allocate and free 3d-specific memory on demand.
*/
-
-
-
-
+/* Use the miext/shadow module to maintain a list of dirty rectangles.
+ * These are blitted to the back buffer to keep both buffers clean
+ * during page-flipping when the 3d application isn't fullscreen.
+ *
+ * Unlike most use of the shadow code, both buffers are in video
+ * memory.
+ *
+ * An alternative to this would be to organize for all on-screen
+ * drawing operations to be duplicated for the two buffers. That
+ * might be faster, but seems like a lot more work...
+ */
+
static void
-I830EnablePageFlip(ScreenPtr pScreen)
+I830DRISetPfMask(ScreenPtr pScreen, int pfMask)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
diff-tree e972265261c421268e4fb806e587378d0adec577 (from 3c08bc7d6974a1a6cf5f9cb81898617032966c52)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Tue Mar 6 16:54:16 2007 +0100
Fix build failure.
Not sure how I missed this before... Thanks to Todd Merrill for reporting.
diff --git a/src/i830_dri.c b/src/i830_dri.c
index bb9de1e..9931acc 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -756,8 +756,9 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScr
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] drmAddMap(third_handle) failed. Triple buffering "
"inactive\n");
- i830_free_memory(pI830->third_buffer);
- sarea->third_handle = pI830->third_buffer = NULL;
+ i830_free_memory(pScrn, pI830->third_buffer);
+ pI830->third_buffer = NULL;
+ sarea->third_handle = 0;
} else
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Third Buffer = 0x%08x\n",
(int)sarea->third_handle);
diff-tree 3c08bc7d6974a1a6cf5f9cb81898617032966c52 (from c25cfafbe1eb380b58b5fc16e94f5cc6f422f0cd)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Tue Mar 6 10:14:47 2007 +0100
Fix some conditionals related to triple buffering.
Guard code that dereferences pI830->third_buffer with tests for that instead of
pI830->TripleBuffer. It could happen that we want to enable triple buffering
but (temporarily) can't because the third buffer couldn't be allocated.
diff --git a/src/i830_dri.c b/src/i830_dri.c
index d69ab3f..bb9de1e 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -748,18 +748,19 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScr
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Back Buffer = 0x%08x\n",
(int)sarea->back_handle);
- if (pI830->TripleBuffer) {
+ if (pI830->third_buffer) {
if (drmAddMap(pI830->drmSubFD,
(drm_handle_t)(sarea->third_offset + pI830->LinearAddr),
sarea->third_size, DRM_AGP, 0,
(drmAddress) &sarea->third_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] drmAddMap(third_handle) failed. Disabling DRI\n");
- DRICloseScreen(pScreen);
- return FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Third Buffer = 0x%08x\n",
- (int)sarea->third_handle);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(third_handle) failed. Triple buffering "
+ "inactive\n");
+ i830_free_memory(pI830->third_buffer);
+ sarea->third_handle = pI830->third_buffer = NULL;
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Third Buffer = 0x%08x\n",
+ (int)sarea->third_handle);
}
if (drmAddMap(pI830->drmSubFD,
@@ -1103,7 +1104,7 @@ I830DRIRefreshArea (ScrnInfoPtr pScrn, i
I830DRIDoRefreshArea(pScrn, num, pbox, pI830->back_buffer->offset);
- if (pI830->TripleBuffer) {
+ if (pI830->third_buffer) {
I830DRIDoRefreshArea(pScrn, num, pbox, pI830->third_buffer->offset);
}
@@ -1207,7 +1208,7 @@ I830DRIInitBuffers(WindowPtr pWin, Regio
I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- if (I830PTR(pScrn)->TripleBuffer) {
+ if (I830PTR(pScrn)->third_buffer) {
I830SelectBuffer(pScrn, I830_SELECT_THIRD);
I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
@@ -1386,7 +1387,7 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
I830SelectBuffer(pScrn, I830_SELECT_BACK);
I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
- if (pI830->TripleBuffer) {
+ if (pI830->third_buffer) {
I830SelectBuffer(pScrn, I830_SELECT_THIRD);
I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
}
@@ -1582,8 +1583,13 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn,
sarea->height = pScreen->height;
sarea->back_offset = pI830->back_buffer->offset;
sarea->back_size = pI830->back_buffer->size;
- sarea->third_offset = pI830->third_buffer->offset;
- sarea->third_size = pI830->third_buffer->size;
+ if (pI830->third_buffer != NULL) {
+ sarea->third_offset = pI830->third_buffer->offset;
+ sarea->third_size = pI830->third_buffer->size;
+ } else {
+ sarea->third_offset = 0;
+ sarea->third_size = 0;
+ }
sarea->depth_offset = pI830->depth_buffer->offset;
sarea->depth_size = pI830->depth_buffer->size;
if (pI830->textures != NULL) {
diff-tree c25cfafbe1eb380b58b5fc16e94f5cc6f422f0cd (from e787d7b698d320a7c45df35d58c5113413561fe2)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Tue Mar 6 10:00:12 2007 +0100
Unify allocation of back buffers.
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 17cad73..54cd6be 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1064,7 +1064,8 @@ myLog2(unsigned int n)
}
static Bool
-i830_allocate_backbuffer(ScrnInfoPtr pScrn)
+i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer,
+ unsigned int *tiled, const char *name)
{
I830Ptr pI830 = I830PTR(pScrn);
unsigned int pitch = pScrn->displayWidth * pI830->cpp;
@@ -1080,69 +1081,23 @@ i830_allocate_backbuffer(ScrnInfoPtr pSc
if (!pI830->disableTiling && IsTileable(pScrn, pitch))
{
size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
- pI830->back_buffer =
- i830_allocate_memory_tiled(pScrn, "back buffer",
- size, pitch, GTT_PAGE_SIZE,
- ALIGN_BOTH_ENDS,
- TILING_XMAJOR);
- pI830->back_tiled = FENCE_XMAJOR;
+ *buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch,
+ GTT_PAGE_SIZE, ALIGN_BOTH_ENDS,
+ TILING_XMAJOR);
+ *tiled = FENCE_XMAJOR;
}
/* Otherwise, just allocate it linear */
- if (pI830->back_buffer == NULL) {
+ if (*buffer == NULL) {
size = ROUND_TO_PAGE(pitch * height);
- pI830->back_buffer = i830_allocate_memory(pScrn, "back buffer",
- size, GTT_PAGE_SIZE,
- ALIGN_BOTH_ENDS);
- pI830->back_tiled = FENCE_LINEAR;
+ *buffer = i830_allocate_memory(pScrn, name, size, GTT_PAGE_SIZE,
+ ALIGN_BOTH_ENDS);
+ *tiled = FENCE_LINEAR;
}
- if (pI830->back_buffer == NULL) {
+ if (*buffer == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Failed to allocate back buffer space.\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static Bool
-i830_allocate_thirdbuffer(ScrnInfoPtr pScrn)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned int pitch = pScrn->displayWidth * pI830->cpp;
- unsigned long size;
- int height;
-
- if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))
- height = pScrn->virtualY;
- else
- height = pScrn->virtualX;
-
- /* Try to allocate on the best tile-friendly boundaries. */
- if (!pI830->disableTiling && IsTileable(pScrn, pitch))
- {
- size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
- pI830->third_buffer =
- i830_allocate_memory_tiled(pScrn, "third buffer",
- size, pitch, GTT_PAGE_SIZE,
- ALIGN_BOTH_ENDS,
- TILING_XMAJOR);
- pI830->third_tiled = FENCE_XMAJOR;
- }
-
- /* Otherwise, just allocate it linear */
- if (pI830->third_buffer == NULL) {
- size = ROUND_TO_PAGE(pitch * height);
- pI830->third_buffer = i830_allocate_memory(pScrn, "third buffer",
- size, GTT_PAGE_SIZE,
- ALIGN_BOTH_ENDS);
- pI830->third_tiled = FENCE_LINEAR;
- }
-
- if (pI830->third_buffer == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Failed to allocate third buffer space.\n");
+ "Failed to allocate %s space.\n", name);
return FALSE;
}
@@ -1246,10 +1201,14 @@ i830_allocate_3d_memory(ScrnInfoPtr pScr
DPRINTF(PFX, "i830_allocate_3d_memory\n");
- if (!i830_allocate_backbuffer(pScrn))
+ if (!i830_allocate_backbuffer(pScrn, &pI830->back_buffer,
+ &pI830->back_tiled, "back buffer"))
return FALSE;
- if (pI830->TripleBuffer && !i830_allocate_thirdbuffer(pScrn)) {
+ if (pI830->TripleBuffer && !i830_allocate_backbuffer(pScrn,
+ &pI830->third_buffer,
+ &pI830->third_tiled,
+ "third buffer")) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Failed to allocate third buffer, triple buffering "
"inactive\n");
diff-tree e787d7b698d320a7c45df35d58c5113413561fe2 (from 6c299aea8e87e72c68c96c03594706c976601ede)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Tue Mar 6 09:35:42 2007 +0100
Remove warnings about potential artifacts with page flipping and mixed 2D/3D.
The artifacts only seemed to occur when EXA was falling back to software for
the front buffer.
diff --git a/man/intel.man b/man/intel.man
index 05a91f7..32aa7c1 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -161,9 +161,9 @@ Default: 32768.
.TP
.BI "Option \*qPageFlip\*q \*q" boolean \*q
Enable support for page flipping. This should improve 3D performance at the
-potential cost of worse performance or artifacts with mixed 2D/3D. Also note
-that this gives no benefit without corresponding support in the Mesa 3D driver
-and may not give the full benefit without triple buffering (see
+potential cost of worse performance with mixed 2D/3D. Also note that this gives
+no benefit without corresponding support in the Mesa 3D driver and may not give
+the full benefit without triple buffering (see
.B "Option \*qTripleBuffer\*q"
).
Default for i810: The option is not used.
diff-tree 6c299aea8e87e72c68c96c03594706c976601ede (from parents)
Merge: 330815251dee808754b328cd2fd60db39f2460eb 4042b27f01fdb94e7fc0d4e991e054fff88479ea
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Tue Mar 6 09:28:52 2007 +0100
Merge remote branch 'origin/master' into i830-pageflip
Conflicts:
src/i830_display.c
src/i830_driver.c
diff --cc src/i830_driver.c
index 8379b6b,0977511..0de4d0d
@@@ -272,9 -272,10 +272,11 @@@
OPTION_COLOR_KEY,
OPTION_CHECKDEVICES,
OPTION_LINEARALLOC,
+ #ifdef XF86DRI_MM
OPTION_INTELTEXPOOL,
- OPTION_INTELMMSIZE
+ OPTION_INTELMMSIZE,
+ #endif
+ OPTION_TRIPLEBUFFER,
} I830Opts;
static OptionInfoRec I830Options[] = {
@@@ -291,9 -292,10 +293,11 @@@
{OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE},
{OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN, {0}, FALSE},
{OPTION_LINEARALLOC, "LinearAlloc", OPTV_INTEGER, {0}, FALSE},
+ #ifdef XF86DRI_MM
{OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_INTELMMSIZE, "AperTexSize", OPTV_INTEGER, {0}, FALSE},
+ #endif
+ {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
/* *INDENT-ON* */
diff-tree 330815251dee808754b328cd2fd60db39f2460eb (from parents)
Merge: 50ba1fff886a7f51b178ac6d3a1ba79a3014b214 015027034e970f1e3bb6ab239f7e0119235e404f
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Mon Mar 5 13:05:20 2007 +0100
Merge remote branch 'origin/master' into i830-pageflip
Conflicts:
src/i830.h
src/i830_dri.c
src/i830_dri.h
src/i830_driver.c
src/i830_memory.c
src/i830_xaa.c
diff --cc src/i830.h
index e26556f,08d9e3e..c704372
@@@ -291,12 -295,13 +298,14 @@@
CreateScreenResourcesProcPtr CreateScreenResources;
int *used3D;
- I830MemRange ContextMem;
+ i830_memory *logical_context;
#ifdef XF86DRI
- I830MemRange BackBuffer;
- I830MemRange ThirdBuffer;
- I830MemRange DepthBuffer;
- I830MemRange TexMem;
+ i830_memory *back_buffer;
++ i830_memory *third_buffer;
+ i830_memory *depth_buffer;
+ i830_memory *textures; /**< Compatibility texture memory */
+ i830_memory *memory_manager; /**< DRI memory manager aperture */
+
int TexGranularity;
int drmMinor;
Bool have3DWindows;
diff --cc src/i830_accel.c
index c76c748,49a9c13..045b3b6
@@@ -226,13 -226,10 +226,13 @@@
switch (buffer) {
#ifdef XF86DRI
case I830_SELECT_BACK:
- pI830->bufferOffset = pI830->BackBuffer.Start;
+ pI830->bufferOffset = pI830->back_buffer->offset;
break;
+ case I830_SELECT_THIRD:
- pI830->bufferOffset = pI830->ThirdBuffer.Start;
++ pI830->bufferOffset = pI830->third_buffer->offset;
+ break;
case I830_SELECT_DEPTH:
- pI830->bufferOffset = pI830->DepthBuffer.Start;
+ pI830->bufferOffset = pI830->depth_buffer->offset;
break;
#endif
default:
diff --cc src/i830_display.c
index 04159e7,d0b21a9..f5a2faa
@@@ -358,34 -387,9 +387,34 @@@
OUTREG(dspsurf, Start);
(void) INREG(dspsurf);
} else {
- OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ OUTREG(dspbase, Start + Offset);
(void) INREG(dspbase);
}
+
+#ifdef XF86DRI
+ if (pI830->directRenderingEnabled) {
+ drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen);
+
+ switch (pipe) {
+ case 0:
+ sPriv->pipeA_x = x;
+ sPriv->pipeA_y = y;
+ sPriv->pipeA_w = crtc->mode.HDisplay;
+ sPriv->pipeA_h = crtc->mode.VDisplay;
+ break;
+ case 1:
+ sPriv->pipeB_x = x;
+ sPriv->pipeB_y = y;
+ sPriv->pipeB_w = crtc->mode.HDisplay;
+ sPriv->pipeB_h = crtc->mode.VDisplay;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Can't update pipe %d in SAREA\n", pipe);
+ break;
+ }
+ }
+#endif
}
/**
diff --cc src/i830_dri.c
index dba1a07,f81251a..d69ab3f
@@@ -1059,61 -1022,6 +1056,61 @@@
}
}
+#ifdef DAMAGE
+/* This should be done *before* XAA syncs,
+ * Otherwise will have to sync again???
+ */
+static void
+I830DRIDoRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox, CARD32 dst)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ int i, cmd, br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
+
+ if (pScrn->bitsPerPixel == 32) {
+ cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+ XY_SRC_COPY_BLT_WRITE_RGB);
+ br13 |= 3 << 24;
+ } else {
+ cmd = (XY_SRC_COPY_BLT_CMD);
+ br13 |= 1 << 24;
+ }
+
+ for (i = 0 ; i < num ; i++, pbox++) {
+ BEGIN_LP_RING(8);
+ OUT_RING(cmd);
+ OUT_RING(br13);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING((pbox->y2 << 16) | pbox->x2);
+ OUT_RING(dst);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING(br13 & 0xffff);
- OUT_RING(pI830->FrontBuffer.Start);
++ OUT_RING(pI830->front_buffer->offset);
+ ADVANCE_LP_RING();
+ }
+}
+
+static void
+I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+
+ /* Don't want to do this when no 3d is active and pages are
+ * right-way-round :
+ */
+ if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0)
+ return;
+
- I830DRIDoRefreshArea(pScrn, num, pbox, pI830->BackBuffer.Start);
++ I830DRIDoRefreshArea(pScrn, num, pbox, pI830->back_buffer->offset);
+
+ if (pI830->TripleBuffer) {
- I830DRIDoRefreshArea(pScrn, num, pbox, pI830->ThirdBuffer.Start);
++ I830DRIDoRefreshArea(pScrn, num, pbox, pI830->third_buffer->offset);
+ }
+
+ DamageEmpty(pI830->pDamage);
+}
+#endif
+
static void
I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
DRIContextType oldContextType, void *oldContext,
@@@ -1582,14 -1458,17 +1580,19 @@@
sarea->width = pScreen->width;
sarea->height = pScreen->height;
- sarea->back_offset = pI830->BackBuffer.Start;
- sarea->back_size = pI830->BackBuffer.Size;
- sarea->third_offset = pI830->ThirdBuffer.Start;
- sarea->third_size = pI830->ThirdBuffer.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->back_offset = pI830->back_buffer->offset;
+ sarea->back_size = pI830->back_buffer->size;
++ sarea->third_offset = pI830->third_buffer->offset;
++ sarea->third_size = pI830->third_buffer->size;
+ sarea->depth_offset = pI830->depth_buffer->offset;
+ sarea->depth_size = pI830->depth_buffer->size;
+ if (pI830->textures != NULL) {
+ sarea->tex_offset = pI830->textures->offset;
+ sarea->tex_size = pI830->textures->size;
+ } else {
+ sarea->tex_offset = 0;
+ sarea->tex_size = 0;
+ }
sarea->log_tex_granularity = pI830->TexGranularity;
sarea->pitch = pScrn->displayWidth;
sarea->virtualX = pScrn->virtualX;
diff --cc src/i830_driver.c
index c950149,ac4e38c..8379b6b
@@@ -854,11 -837,9 +839,8 @@@
char *s;
pointer pVBEModule = NULL;
const char *chipname;
- Bool enable;
int num_pipe;
int max_width, max_height;
- #ifdef XF86DRI
- unsigned long savedMMSize;
- #endif
if (pScrn->numEntities != 1)
return FALSE;
@@@ -2490,7 -2136,250 +2147,254 @@@
pI830 = I830PTR(pScrn);
hwp = VGAHWPTR(pScrn);
- pScrn->displayWidth = pI830->displayWidth;
+ pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+
+ /*
+ * The "VideoRam" config file parameter specifies the maximum amount of
+ * memory that will be used/allocated. When not present, we allow the
+ * driver to allocate as much memory as it wishes to satisfy its
+ * allocations, but if agpgart support isn't available, it gets limited
+ * to the amount of pre-allocated ("stolen") memory.
+ *
+ * Note that in using this value for allocator initialization, we're
+ * limiting aperture allocation to the VideoRam option, rather than limiting
+ * actual memory allocation, so alignment and things will cause less than
+ * VideoRam to be actually used.
+ */
+ if (pI830->pEnt->device->videoRam == 0) {
+ from = X_DEFAULT;
+ pScrn->videoRam = pI830->FbMapSize / KB(1);
+ } else {
+ from = X_CONFIG;
+ pScrn->videoRam = pI830->pEnt->device->videoRam;
+ }
+
+ /* Limit videoRam to how much we might be able to allocate from AGP */
+ sys_mem = I830CheckAvailableMemory(pScrn);
+ if (sys_mem == -1) {
+ if (pScrn->videoRam > pI830->stolen_size / KB(1)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "/dev/agpgart is either not available, or no memory "
+ "is available\nfor allocation. "
+ "Using pre-allocated memory only.\n");
+ pScrn->videoRam = pI830->stolen_size / KB(1);
+ }
+ pI830->StolenOnly = TRUE;
+ } else {
+ if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) {
+ pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024);
+ from = X_PROBED;
+ if (sys_mem + (pI830->stolen_size / 1024) <
+ pI830->pEnt->device->videoRam)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "VideoRAM reduced to %d kByte "
+ "(limited to available sysmem)\n", pScrn->videoRam);
+ }
+ }
+ }
+
+ /* Limit video RAM to the actual aperture size */
+ if (pScrn->videoRam > pI830->FbMapSize / 1024) {
+ pScrn->videoRam = pI830->FbMapSize / 1024;
+ if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "VideoRam reduced to %d kByte (limited to aperture "
+ "size)\n",
+ pScrn->videoRam);
+ }
+ }
+
+ /* Make sure it's on a page boundary */
+ if (pScrn->videoRam & 3) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB "
+ "(page aligned - was %d KB)\n",
+ pScrn->videoRam & ~3, pScrn->videoRam);
+ pScrn->videoRam &= ~3;
+ }
+
+ /* Set up our video memory allocator for the chosen videoRam */
+ if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't initialize video memory allocator\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex,
+ pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT,
+ "VideoRam: %d KB\n", pScrn->videoRam);
+
+ if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES,
+ &(pI830->CacheLines))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n",
+ pI830->CacheLines);
+ } else {
+ pI830->CacheLines = -1;
+ }
+
+ pI830->disableTiling = FALSE;
+
+ if (I830IsPrimary(pScrn)) {
+ /* Alloc our pointers for the primary head */
+ if (!pI830->LpRing)
+ pI830->LpRing = xcalloc(1, sizeof(I830RingBuffer));
+ if (!pI830->overlayOn)
+ pI830->overlayOn = xalloc(sizeof(Bool));
+ if (!pI830->used3D)
+ pI830->used3D = xalloc(sizeof(int));
+ if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not allocate primary data structures.\n");
+ return FALSE;
+ }
+ *pI830->overlayOn = FALSE;
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->XvInUse = -1;
+ } else {
+ /* Make our second head point to the first heads structures */
+ pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pI830->LpRing = pI8301->LpRing;
+ pI830->overlay_regs = pI8301->overlay_regs;
+ pI830->overlayOn = pI8301->overlayOn;
+ pI830->used3D = pI8301->used3D;
+ }
+
+ #if defined(XF86DRI)
+ /*
+ * If DRI is potentially usable, check if there is enough memory available
+ * for it, and if there's also enough to allow tiling to be enabled.
+ */
+
+ if (!I830CheckDRIAvailable(pScrn)) {
+ pI830->directRenderingDisabled = TRUE;
+ pI830->mmSize = 0;
+ }
+
+ if (!pI830->directRenderingDisabled) {
+ int savedDisplayWidth = pScrn->displayWidth;
+ Bool tiled = FALSE;
+
+ #ifdef I830_XV
+ /*
+ * Set this so that the overlay allocation is factored in when
+ * appropriate.
+ */
+ pI830->XvEnabled = !pI830->XvDisabled;
+ #endif
+
+ if (IS_I965G(pI830)) {
+ int tile_pixels = 512 / pI830->cpp;
+ pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
+ ~(tile_pixels - 1);
+ tiled = TRUE;
+ } else {
+ /* Good pitches to allow tiling. Don't care about pitches < 1024
+ * pixels.
+ */
+ static const int pitches[] = {
+ 1024,
+ 2048,
+ 4096,
+ 8192,
+ 0
+ };
+
+ for (i = 0; pitches[i] != 0; i++) {
+ if (pitches[i] >= pScrn->displayWidth) {
+ pScrn->displayWidth = pitches[i];
+ tiled = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* Attempt several rounds of allocation to get 2d and 3d memory to fit:
+ *
+ * 0: tiled, large memory manager
+ * 1: tiled, small memory manager
+ * 2: untiled, large
+ * 3: untiled, small
+ */
+
+ pI830->disableTiling = FALSE;
+ savedMMSize = pI830->mmSize;
+ for (i = 0; i < 4; i++) {
+ if (!tiled && i < 2)
+ continue;
+
+ if (i >= 2) {
+ /* For further allocations, disable tiling */
+ pI830->disableTiling = TRUE;
+ pScrn->displayWidth = savedDisplayWidth;
++ if (pI830->allowPageFlip)
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Couldn't allocate tiled memory, page flipping "
++ "disabled\n");
+ pI830->allowPageFlip = FALSE;
+ }
+
+ if (i & 1) {
+ /* For this allocation, switch to a smaller DRI memory manager
+ * size.
+ */
+ pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE;
+ } else {
+ pI830->mmSize = savedMMSize;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Attempting memory allocation with %s buffers and \n"
+ "\t %s DRI memory manager reservation:\n",
+ (i & 2) ? "untiled" : "tiled",
+ (i & 1) ? "small" : "large");
+
+ if (i830_allocate_2d_memory(pScrn) &&
+ i830_allocate_3d_memory(pScrn))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Success.\n");
+ if (pScrn->displayWidth != savedDisplayWidth) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Increasing the scanline pitch to allow tiling mode "
+ "(%d -> %d).\n",
+ savedDisplayWidth, pScrn->displayWidth);
+ }
+ allocation_done = TRUE;
+ break;
+ }
+
+ i830_reset_allocations(pScrn);
+ }
+
+ if (i == 4) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Not enough video memory. Disabling DRI.\n");
+ pI830->mmSize = 0;
+ pI830->directRenderingDisabled = TRUE;
+ }
+ } else
+ #endif
+ pI830->disableTiling = TRUE; /* no DRI - so disableTiling */
+
+ if (!allocation_done) {
+ if (!i830_allocate_2d_memory(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate video memory\n");
+ return FALSE;
+ }
+ allocation_done = TRUE;
+ }
+
+ i830_describe_allocations(pScrn, 1, "");
+
+ if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Cannot support DRI with frame buffer width > 2048.\n");
+ pI830->disableTiling = TRUE;
+ pI830->directRenderingDisabled = TRUE;
+ }
+
+ pScrn->displayWidth = pScrn->displayWidth;
#ifdef HAS_MTRR_SUPPORT
{
@@@ -2663,30 -2512,9 +2527,12 @@@
pI830->directRenderingEnabled = FALSE;
#endif
- /*
- * After the 3D allocations have been done, see if there's any free space
- * that can be added to the framebuffer allocation.
- */
- if (I830IsPrimary(pScrn)) {
- I830Allocate2DMemory(pScrn, 0);
-
- DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n");
- if (!I830DoPoolAllocation(pScrn, &(pI830->StolenPool)))
- return FALSE;
-
- DPRINTF(PFX, "assert( if(!I830FixupOffsets(pScrn)) )\n");
- if (!I830FixupOffsets(pScrn))
- return FALSE;
- }
-
#ifdef XF86DRI
- if (pI830->directRenderingEnabled) {
- I830SetupMemoryTiling(pScrn);
+ if (pI830->directRenderingEnabled)
pI830->directRenderingEnabled = I830DRIDoMappings(pScreen);
- }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page Flipping %sabled\n",
+ pI830->allowPageFlip ? "en" : "dis");
#endif
DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n");
diff --cc src/i830_memory.c
index a952b70,5cddf17..f5cffba
@@@ -62,259 -107,514 +107,521 @@@
#include "i830.h"
#include "i810_reg.h"
- static int nextTile = 0;
- static unsigned int tileGeneration = -1;
+ #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
+
+ enum tile_format {
+ TILING_NONE,
+ TILING_XMAJOR,
+ TILING_YMAJOR
+ };
+
+ static void i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset,
+ unsigned int pitch, unsigned int size,
+ enum tile_format tile_format);
+ /**
+ * Returns the fence size for a tiled area of the given size.
+ */
static unsigned long
- GetBestTileAlignment(unsigned long size)
+ i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size)
{
- unsigned long i;
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long i;
+ unsigned long start;
+
+ if (IS_I965G(pI830)) {
+ /* The 965 can have fences at any page boundary. */
+ return ALIGN(size, GTT_PAGE_SIZE);
+ } else {
+ /* Align the size to a power of two greater than the smallest fence
+ * size.
+ */
+ if (IS_I9XX(pI830))
+ start = MB(1);
+ else
+ start = KB(512);
- for (i = KB(512); i < size; i <<= 1)
- ;
+ for (i = start; i < size; i <<= 1)
+ ;
- if (i > MB(64))
- i = MB(64);
+ return i;
+ }
+ }
+
+ static Bool
+ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
+ {
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (mem == NULL || mem->key == -1 || mem->bound || !pI830->gtt_acquired)
+ return TRUE;
- return i;
+ if (xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) {
+ mem->bound = TRUE;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+
+ return TRUE;
}
- /*
- * Allocate memory from the given pool. Grow the pool if needed and if
- * possible.
+ static Bool
+ i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
+ {
+ if (mem == NULL || mem->key == -1 || !mem->bound)
+ return TRUE;
+
+ if (xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) {
+ mem->bound = FALSE;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+
+ void
+ i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem)
+ {
+ if (mem == NULL)
+ return;
+
+ i830_unbind_memory(pScrn, mem);
+
+ /* Disconnect from the list of allocations */
+ if (mem->prev != NULL)
+ mem->prev->next = mem->next;
+ if (mem->next != NULL)
+ mem->next->prev = mem->prev;
+
+ /* Free any AGP memory. */
+ i830_unbind_memory(pScrn, mem);
+
+ if (mem->key != -1) {
+ xf86DeallocateGARTMemory(pScrn->scrnIndex, mem->key);
+ mem->key = -1;
+ }
+
+ xfree(mem->name);
+ xfree(mem);
+ }
+
+ /* Resets the state of the aperture allocator, freeing all memory that had
+ * been allocated.
*/
- static unsigned long
- AllocFromPool(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool,
- long size, unsigned long alignment, int flags)
+ void
+ i830_reset_allocations(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
- long needed, start, end;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
-
- if (!result || !pool || !size)
- return 0;
-
- /* Calculate how much space is needed. */
- if (alignment <= GTT_PAGE_SIZE)
- needed = size;
- else {
- if (flags & ALLOCATE_AT_BOTTOM) {
- start = ROUND_TO(pool->Free.Start, alignment);
- if (flags & ALIGN_BOTH_ENDS)
- end = ROUND_TO(start + size, alignment);
- else
- end = start + size;
- needed = end - pool->Free.Start;
- } else { /* allocate at top */
- if (flags & ALIGN_BOTH_ENDS)
- end = ROUND_DOWN_TO(pool->Free.End, alignment);
- else
- end = pool->Free.End;
-
- start = ROUND_DOWN_TO(end - size, alignment);
- needed = end - start;
- }
- }
- if (needed > pool->Free.Size) {
- long extra;
- /* See if the pool can be grown. */
- if (pI830->StolenOnly && !dryrun)
- return 0;
- extra = needed - pool->Free.Size;
- extra = ROUND_TO_PAGE(extra);
- if (extra > pI830->FreeMemory) {
- if (dryrun)
- pI830->FreeMemory = extra;
- else
- return 0;
- }
-
- if (!dryrun && ((long)extra > pI830->MemoryAperture.Size))
- return 0;
-
- pool->Free.Size += extra;
- pool->Free.End += extra;
- pool->Total.Size += extra;
- pool->Total.End += extra;
- pI830->FreeMemory -= extra;
- pI830->MemoryAperture.Start += extra;
- pI830->MemoryAperture.Size -= extra;
- }
- if (flags & ALLOCATE_AT_BOTTOM) {
- result->Start = ROUND_TO(pool->Free.Start, alignment);
- pool->Free.Start += needed;
- result->End = pool->Free.Start;
- } else {
- result->Start = ROUND_DOWN_TO(pool->Free.End - size, alignment);
- pool->Free.End -= needed;
- result->End = result->Start + needed;
- }
- pool->Free.Size = pool->Free.End - pool->Free.Start;
- result->Size = result->End - result->Start;
- result->Pool = pool;
- result->Alignment = alignment;
- return needed;
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
+
+ /* While there is any memory between the start and end markers, free it. */
+ while (pI830->memory_list->next->next != NULL)
+ i830_free_memory(pScrn, pI830->memory_list->next);
+
+ /* Null out the pointers for all the allocations we just freed. This is
+ * kind of gross, but at least it's just one place now.
+ */
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
+
+ intel_crtc->cursor_mem = NULL;
+ intel_crtc->cursor_mem_argb = NULL;
+ }
+
+ pI830->front_buffer = NULL;
+ pI830->front_buffer_2 = NULL;
+ pI830->xaa_scratch = NULL;
+ pI830->xaa_scratch_2 = NULL;
+ pI830->exa_offscreen = NULL;
+ pI830->exa_965_state = NULL;
+ pI830->overlay_regs = NULL;
+ pI830->xaa_linear = NULL;
+ pI830->logical_context = NULL;
+ pI830->back_buffer = NULL;
++ pI830->third_buffer = NULL;
+ pI830->depth_buffer = NULL;
+ pI830->textures = NULL;
+ pI830->memory_manager = NULL;
+ pI830->LpRing->mem = NULL;
+
+ /* Reset the fence register allocation. */
+ pI830->next_fence = 0;
+ memset(pI830->fence, 0, sizeof(pI830->fence));
}
- static unsigned long
- AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, long size,
- unsigned long alignment, int flags)
+ void
+ i830_free_3d_memory(ScrnInfoPtr pScrn)
+ {
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ i830_free_memory(pScrn, pI830->back_buffer);
+ pI830->back_buffer = NULL;
++ i830_free_memory(pScrn, pI830->third_buffer);
++ pI830->third_buffer = NULL;
+ i830_free_memory(pScrn, pI830->depth_buffer);
+ pI830->depth_buffer = NULL;
+ i830_free_memory(pScrn, pI830->textures);
+ pI830->textures = NULL;
+ i830_free_memory(pScrn, pI830->memory_manager);
+ pI830->memory_manager = NULL;
+ }
+
+ /**
+ * Initialize's the driver's video memory allocator to allocate in the
+ * given range.
+ */
+ Bool
+ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset,
+ unsigned long size)
{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long start, end;
- unsigned long newApStart, newApEnd;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
-
- if (!result || !size)
- return 0;
-
- if ((flags & ALLOCATE_AT_BOTTOM) && pI830->StolenMemory.Size != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "AllocFromAGP(): can't allocate from "
- "bottom when there is stolen memory\n");
- return 0;
- }
-
- if (size > pI830->FreeMemory) {
- if (dryrun)
- pI830->FreeMemory = size;
- else
- return 0;
- }
-
- /* Calculate offset */
- if (flags & ALLOCATE_AT_BOTTOM) {
- start = ROUND_TO(pI830->MemoryAperture.Start, alignment);
- if (flags & ALIGN_BOTH_ENDS)
- end = ROUND_TO(start + size, alignment);
- else
- end = start + size;
- newApStart = end;
- newApEnd = pI830->MemoryAperture.End;
- } else {
- if (flags & ALIGN_BOTH_ENDS)
- end = ROUND_DOWN_TO(pI830->MemoryAperture.End, alignment);
- else
- end = pI830->MemoryAperture.End;
- start = ROUND_DOWN_TO(end - size, alignment);
- newApStart = pI830->MemoryAperture.Start;
- newApEnd = start;
- }
-
- if (!dryrun) {
- if (newApStart > newApEnd)
- return 0;
-
- if (flags & NEED_PHYSICAL_ADDR)
- result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
- &(result->Physical));
- else
- result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
-
- if (result->Key == -1)
- return 0;
- }
-
- pI830->allocatedMemory += size;
- pI830->MemoryAperture.Start = newApStart;
- pI830->MemoryAperture.End = newApEnd;
- pI830->MemoryAperture.Size = newApEnd - newApStart;
- pI830->FreeMemory -= size;
- result->Start = start;
- result->End = start + size;
- result->Size = size;
- result->Offset = start;
- result->Alignment = alignment;
- result->Pool = NULL;
+ I830Ptr pI830 = I830PTR(pScrn);
+ i830_memory *start, *end;
+
+ start = xcalloc(1, sizeof(*start));
+ if (start == NULL)
+ return FALSE;
+ start->name = xstrdup("start marker");
+ if (start->name == NULL) {
+ xfree(start);
+ return FALSE;
+ }
+ end = xcalloc(1, sizeof(*end));
+ if (end == NULL) {
+ xfree(start->name);
+ xfree(start);
+ return FALSE;
+ }
+ end->name = xstrdup("end marker");
+ if (end->name == NULL) {
+ xfree(start->name);
+ xfree(start);
+ xfree(end);
+ return FALSE;
+ }
+
+ start->key = -1;
+ start->offset = offset;
+ start->end = start->offset;
+ start->size = 0;
+ start->next = end;
+ end->key = -1;
+ end->offset = offset + size;
+ end->end = end->offset;
+ end->size = 0;
+ end->prev = start;
+
+ pI830->memory_list = start;
+
+ return TRUE;
+ }
+
+ /* Allocate aperture space for the given size and alignment, and returns the
+ * memory allocation.
+ *
+ * Allocations are a minimum of a page, and will be at least page-aligned.
+ */
+ static i830_memory *
+ i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name,
+ long size, unsigned long alignment, int flags)
+ {
+ I830Ptr pI830 = I830PTR(pScrn);
+ i830_memory *mem, *scan;
+
+ mem = xcalloc(1, sizeof(*mem));
+ if (mem == NULL)
+ return NULL;
+
+ /* No memory allocated to back the region */
+ mem->key = -1;
+
+ mem->name = xstrdup(name);
+ if (mem->name == NULL) {
+ xfree(mem);
+ return NULL;
+ }
+ /* Only allocate page-sized increments. */
+ size = ALIGN(size, GTT_PAGE_SIZE);
+ mem->size = size;
+
+ if (alignment < GTT_PAGE_SIZE)
+ alignment = GTT_PAGE_SIZE;
+
+ for (scan = pI830->memory_list; scan->next != NULL; scan = scan->next) {
+ mem->offset = scan->end;
+ /* For allocations requiring physical addresses, we have to use AGP
+ * memory, so move the allocation up out of stolen memory.
+ */
+ if ((flags & NEED_PHYSICAL_ADDR) && mem->offset < pI830->stolen_size)
+ mem->offset = pI830->stolen_size;
+ mem->offset = ROUND_TO(mem->offset, alignment);
+
+ mem->end = mem->offset + size;
+ if (flags & ALIGN_BOTH_ENDS)
+ mem->end = ROUND_TO(mem->end, alignment);
+ if (mem->end <= scan->next->offset)
+ break;
+ }
+ if (scan->next == NULL) {
+ /* Reached the end of the list, and didn't find space */
+ xfree(mem->name);
+ xfree(mem);
+ return NULL;
+ }
+ /* Insert new allocation into the list */
+ mem->prev = scan;
+ mem->next = scan->next;
+ scan->next = mem;
+ mem->next->prev = scan;
+
+ return mem;
+ }
+
+ /**
+ * Allocates the AGP memory necessary for the part of a memory allocation not
+ * already covered by the stolen memory.
+ *
+ * The memory is automatically bound if we have the VT.
+ */
+ static Bool
+ i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags)
+ {
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size;
+
+ if (mem->key != -1)
+ return TRUE;
+
+ if (mem->offset + mem->size <= pI830->stolen_size &&
+ !(flags & NEED_PHYSICAL_ADDR))
+ {
+ return TRUE;
+ }
+
+ if (mem->offset < pI830->stolen_size)
+ mem->agp_offset = pI830->stolen_size;
+ else
+ mem->agp_offset = mem->offset;
+
+ size = mem->size - (mem->agp_offset - mem->offset);
+
+ if (flags & NEED_PHYSICAL_ADDR)
+ mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
+ &mem->bus_addr);
+ else
+ mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+ if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0))
+ {
+ return FALSE;
+ }
+
+ if (!i830_bind_memory(pScrn, mem)) {
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+
+ /* Allocates video memory at the given size and alignment.
+ *
+ * The memory will be bound automatically when the driver is in control of the
+ * VT.
+ */
+ static i830_memory *
+ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
+ unsigned long size, unsigned long alignment, int flags)
+ {
+ i830_memory *mem;
+
+ mem = i830_allocate_aperture(pScrn, name, size, alignment, flags);
+ if (mem == NULL)
+ return NULL;
+
+ if (!i830_allocate_agp_memory(pScrn, mem, flags)) {
+ i830_free_memory(pScrn, mem);
+ return NULL;
+ }
+
+ return mem;
+ }
+
+ /* Allocate a tiled region with the given size and pitch.
+ *
+ * As is, we might miss out on tiling some allocations on older hardware with
+ * large framebuffer size and a small aperture size, where the first
+ * allocations use a large alignment even though we've got fences to spare, and
+ * the later allocations can't find enough aperture space left. We could do
+ * some search across all allocation options to fix this, probably, but that
+ * would be another rewrite.
+ */
+ static i830_memory *
+ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name,
+ unsigned long size, unsigned long pitch,
+ unsigned long alignment, int flags,
+ enum tile_format tile_format)
+ {
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long aper_size;
+ unsigned long aper_align;
+ i830_memory *mem;
+ int fence_divide, i;
+
+ if (tile_format == TILING_NONE)
+ return i830_allocate_memory(pScrn, name, size, alignment, flags);
+
+ /* Only allocate page-sized increments. */
+ size = ALIGN(size, GTT_PAGE_SIZE);
+
+ /* Check for maximum tiled region size */
+ if (IS_I9XX(pI830)) {
+ if (size > MB(128))
+ return NULL;
+ } else {
+ if (size > MB(64))
+ return NULL;
+ }
- return size;
+ aper_size = i830_get_fence_size(pScrn, size);
+ if (IS_I965G(pI830)) {
+ aper_align = GTT_PAGE_SIZE;
+ } else {
+ /* The offset has to be aligned to at least the size of the fence
+ * region.
+ */
+ aper_align = aper_size;
+ }
+ if (aper_align < alignment)
+ aper_align = alignment;
+
+ fence_divide = 1;
+ mem = i830_allocate_aperture(pScrn, name, aper_size, aper_align, flags);
+ if (mem == NULL && !IS_I965G(pI830)) {
+ /* For the older hardware with stricter fencing limits, if we
+ * couldn't allocate with the large alignment, try relaxing the
+ * alignment requirements and using more fences to cover the area.
+ */
+ for (fence_divide = 2; fence_divide <= 4 && mem == NULL;
+ fence_divide *= 2)
+ {
+ /* Check that it's not too small for fencing. */
+ if (i830_get_fence_size(pScrn, aper_align / fence_divide) !=
+ aper_align / fence_divide)
+ {
+ break;
+ }
+
+ mem = i830_allocate_aperture(pScrn, name, aper_size,
+ aper_align / fence_divide, flags);
+ }
+ }
+
+ if (mem == NULL)
+ return NULL;
+
+ /* Make sure we've got enough free fence regs. It's pretty hard to run
+ * out, luckily, with 8 even on older hardware and us only tiling
+ * front/back/depth buffers.
+ */
+ if (pI830->next_fence + fence_divide >
+ (IS_I965G(pI830) ? FENCE_NEW_NR : FENCE_NR))
+ {
+ i830_free_memory(pScrn, mem);
+ return NULL;
+ }
+
+ /* Allocate any necessary AGP memory to back this allocation */
+ if (!i830_allocate_agp_memory(pScrn, mem, flags)) {
+ i830_free_memory(pScrn, mem);
+ return NULL;
+ }
+
+ /* Set up the fence registers. */
+ for (i = 0; i < fence_divide; i++) {
+ i830_set_fence(pScrn, pI830->next_fence++,
+ mem->offset + mem->size * i / fence_divide, pitch,
+ mem->size / fence_divide, tile_format);
+ }
+
+ mem->size = size;
+
+ return mem;
+ }
+
+ static void
+ i830_describe_tiling(ScrnInfoPtr pScrn, int verbosity, const char *prefix,
+ i830_memory *mem, unsigned int tiling_mode)
+ {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s%s is %stiled\n", prefix, mem->name,
+ (tiling_mode == FENCE_LINEAR) ? "not " : "");
}
void
- I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range)
+ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ I830Ptr pI830 = I830PTR(pScrn);
+ i830_memory *mem;
- if (!range || range->Size == 0)
- return;
+ if (pI830->memory_list == NULL) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sMemory allocator not initialized\n", prefix);
+ return;
+ }
+
+ if (pI830->memory_list->next->next == NULL) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sNo memory allocations\n", prefix);
+ 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;
- 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,
- long size, unsigned long alignment, int flags)
- {
- I830Ptr pI830 = I830PTR(pScrn);
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
-
- if (!result)
- return 0;
-
- /* Make sure these are initialised. */
- result->Size = 0;
- result->Key = -1;
-
- if (!size) {
- return 0;
- }
-
- switch (flags & FROM_MASK) {
- case FROM_POOL_ONLY:
- return AllocFromPool(pScrn, result, pool, size, alignment, flags);
- case FROM_NEW_ONLY:
- if (!dryrun && (pI830->StolenOnly || (pI830->FreeMemory <= 0)))
- return 0;
- return AllocFromAGP(pScrn, result, size, alignment, flags);
- case FROM_ANYWHERE:
- if ((!(flags & ALLOCATE_AT_BOTTOM) && (pI830->FreeMemory >= size)) ||
- (flags & NEED_PHYSICAL_ADDR))
- return AllocFromAGP(pScrn, result, size, alignment, flags);
- else
- return AllocFromPool(pScrn, result, pool, size, alignment, flags);
- default:
- /* Shouldn't happen. */
- return 0;
- }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sMemory allocation layout:\n", prefix);
+
+ for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) {
+
+ if (mem->offset >= pI830->stolen_size &&
+ mem->prev->offset < pI830->stolen_size)
+ {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s0x%08lx: end of stolen memory\n",
+ prefix, pI830->stolen_size);
+ }
+
+ if (mem->bus_addr == 0) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix,
+ mem->offset, mem->end - 1, mem->name,
+ mem->size / 1024);
+ } else {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s0x%08lx-0x%08lx: %s (%ld kB, 0x%08lx physical)\n",
+ prefix,
+ mem->offset, mem->end - 1, mem->name,
+ mem->size / 1024, mem->bus_addr);
+ }
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s0x%08lx: end of aperture\n",
+ prefix, pI830->FbMapSize);
+
+ if (pI830->front_buffer != NULL) {
+ i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer,
+ pI830->front_tiled);
+ }
+ if (pI830->back_buffer != NULL) {
+ i830_describe_tiling(pScrn, verbosity, prefix, pI830->back_buffer,
+ pI830->back_tiled);
+ }
++ if (pI830->third_buffer != NULL) {
++ i830_describe_tiling(pScrn, verbosity, prefix, pI830->third_buffer,
++ pI830->third_tiled);
++ }
+ if (pI830->depth_buffer != NULL) {
+ i830_describe_tiling(pScrn, verbosity, prefix, pI830->depth_buffer,
+ pI830->depth_tiled);
+ }
}
static Bool
@@@ -1045,567 -1042,293 +1049,344 @@@
static unsigned int
myLog2(unsigned int n)
{
- unsigned int log2 = 1;
+ unsigned int log2 = 1;
- while (n > 1) {
- n >>= 1;
- log2++;
- }
- return log2;
+ while (n > 1) {
+ n >>= 1;
+ log2++;
+ }
+ return log2;
}
- Bool
- I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags)
+ static Bool
+ i830_allocate_backbuffer(ScrnInfoPtr pScrn)
{
- 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;
-
- /* Back Buffer */
- memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer));
- pI830->BackBuffer.Key = -1;
- tileable = !(flags & ALLOC_NO_TILING) &&
- IsTileable(pScrn, 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 >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
- alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer),
- &(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->BackBuffer),
- &(pI830->StolenPool), size, align,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- }
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate back buffer space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the back buffer at 0x%lx.\n", s,
- alloced / 1024, pI830->BackBuffer.Start);
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+ unsigned long size;
+ int height;
+
+ if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))
+ height = pScrn->virtualY;
+ else
+ height = pScrn->virtualX;
+
+ /* Try to allocate on the best tile-friendly boundaries. */
+ if (!pI830->disableTiling && IsTileable(pScrn, pitch))
+ {
+ size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
+ pI830->back_buffer =
+ i830_allocate_memory_tiled(pScrn, "back buffer",
+ size, pitch, GTT_PAGE_SIZE,
+ ALIGN_BOTH_ENDS,
+ TILING_XMAJOR);
+ pI830->back_tiled = FENCE_XMAJOR;
+ }
+
+ /* Otherwise, just allocate it linear */
+ if (pI830->back_buffer == NULL) {
+ size = ROUND_TO_PAGE(pitch * height);
+ pI830->back_buffer = i830_allocate_memory(pScrn, "back buffer",
+ size, GTT_PAGE_SIZE,
+ ALIGN_BOTH_ENDS);
+ pI830->back_tiled = FENCE_LINEAR;
+ }
- return TRUE;
+ if (pI830->back_buffer == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate back buffer space.\n");
+ return FALSE;
+ }
+
+ return TRUE;
}
- Bool
- I830AllocateThirdBuffer(ScrnInfoPtr pScrn, const int flags)
+ static Bool
++i830_allocate_thirdbuffer(ScrnInfoPtr pScrn)
+{
- 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;
-
- /* Third Buffer */
- memset(&(pI830->ThirdBuffer), 0, sizeof(pI830->ThirdBuffer));
- pI830->ThirdBuffer.Key = -1;
- tileable = !(flags & ALLOC_NO_TILING) &&
- IsTileable(pScrn, 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 >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
- alloced = I830AllocVidMem(pScrn, &(pI830->ThirdBuffer),
- &(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->ThirdBuffer),
- &(pI830->StolenPool), size, align,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- }
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate third buffer space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the third buffer at 0x%lx.\n", s,
- alloced / 1024, pI830->ThirdBuffer.Start);
++ I830Ptr pI830 = I830PTR(pScrn);
++ unsigned int pitch = pScrn->displayWidth * pI830->cpp;
++ unsigned long size;
++ int height;
++
++ if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))
++ height = pScrn->virtualY;
++ else
++ height = pScrn->virtualX;
++
++ /* Try to allocate on the best tile-friendly boundaries. */
++ if (!pI830->disableTiling && IsTileable(pScrn, pitch))
++ {
++ size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
++ pI830->third_buffer =
++ i830_allocate_memory_tiled(pScrn, "third buffer",
++ size, pitch, GTT_PAGE_SIZE,
++ ALIGN_BOTH_ENDS,
++ TILING_XMAJOR);
++ pI830->third_tiled = FENCE_XMAJOR;
++ }
++
++ /* Otherwise, just allocate it linear */
++ if (pI830->third_buffer == NULL) {
++ size = ROUND_TO_PAGE(pitch * height);
++ pI830->third_buffer = i830_allocate_memory(pScrn, "third buffer",
++ size, GTT_PAGE_SIZE,
++ ALIGN_BOTH_ENDS);
++ pI830->third_tiled = FENCE_LINEAR;
++ }
+
- return TRUE;
++ if (pI830->third_buffer == NULL) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Failed to allocate third buffer space.\n");
++ return FALSE;
++ }
++
++ return TRUE;
+}
+
- Bool
- I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags)
++static Bool
+ i830_allocate_depthbuffer(ScrnInfoPtr pScrn)
{
- 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, 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 >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
- alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
- &(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->DepthBuffer),
- &(pI830->StolenPool), size, align,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- }
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate depth buffer space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the depth buffer at 0x%lx.\n", s,
- alloced / 1024, pI830->DepthBuffer.Start);
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size;
+ unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+ int height;
+
+ /* XXX: this rotation stuff is bogus */
+ if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))
+ height = pScrn->virtualY;
+ else
+ height = pScrn->virtualX;
+
+ /* First try allocating it tiled */
+ if (!pI830->disableTiling && IsTileable(pScrn, pitch))
+ {
+ size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
+
+ pI830->depth_buffer =
+ i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch,
+ GTT_PAGE_SIZE, ALIGN_BOTH_ENDS,
+ TILING_YMAJOR);
+ pI830->depth_tiled = FENCE_YMAJOR;
+ }
+
+ /* Otherwise, allocate it linear. */
+ if (pI830->depth_buffer == NULL) {
+ size = ROUND_TO_PAGE(pitch * height);
+ pI830->depth_buffer =
+ i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE,
+ 0);
+ pI830->depth_tiled = FENCE_LINEAR;
+ }
- return TRUE;
+ if (pI830->depth_buffer == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate depth buffer space.\n");
+ return FALSE;
+ }
+
+ return TRUE;
}
- Bool
- I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags)
+ static Bool
+ i830_allocate_texture_memory(ScrnInfoPtr pScrn)
{
- 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));
- pI830->TexMem.Key = -1;
-
- if (pI830->mmModeFlags & I830_KERNEL_TEX) {
-
- if (dryrun && pI830->pEnt->device->videoRam == 0) {
- /* If we're laying out a default-sized allocation, then don't be
- * too greedy and just ask for 32MB.
- */
- size = MB(32);
- } else {
- size = GetFreeSpace(pScrn);
- }
- if (dryrun && (size < MB(1)))
- size = MB(1);
- i = myLog2(size / I830_NR_TEX_REGIONS);
- if (i < I830_LOG_MIN_TEX_REGION_SIZE)
- i = I830_LOG_MIN_TEX_REGION_SIZE;
- pI830->TexGranularity = i;
- /* Truncate size */
- size >>= i;
- size <<= i;
- if (size < KB(512)) {
- if (!dryrun) {
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size;
+ int i;
+
+ if (pI830->mmModeFlags & I830_KERNEL_MM) {
+ pI830->memory_manager =
+ i830_allocate_aperture(pScrn, "DRI memory manager",
+ pI830->mmSize * KB(1), GTT_PAGE_SIZE,
+ ALIGN_BOTH_ENDS);
+ /* XXX: try memory manager size backoff here? */
+ if (pI830->memory_manager == NULL)
+ return FALSE;
+ }
+
+ if (pI830->mmModeFlags & I830_KERNEL_TEX) {
+ /* XXX: auto-sizing */
+ size = MB(32);
+ i = myLog2(size / I830_NR_TEX_REGIONS);
+ if (i < I830_LOG_MIN_TEX_REGION_SIZE)
+ i = I830_LOG_MIN_TEX_REGION_SIZE;
+ pI830->TexGranularity = i;
+ /* Truncate size */
+ size >>= i;
+ size <<= i;
+ if (size < KB(512)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Less than 512 kBytes for texture space (real %ld kBytes).\n",
+ "Less than 512 kBytes for texture space (real %ld"
+ "kBytes).\n",
size / 1024);
- }
- return FALSE;
- }
- alloced = I830AllocVidMem(pScrn, &(pI830->TexMem),
- &(pI830->StolenPool), size, GTT_PAGE_SIZE,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ return FALSE;
+ }
+ pI830->textures = i830_allocate_memory(pScrn, "textures", size,
+ GTT_PAGE_SIZE, 0);
+ if (pI830->textures == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Failed to allocate texture space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for textures at 0x%lx\n", s,
- alloced / 1024, pI830->TexMem.Start);
- }
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
Bool
- I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
+ i830_allocate_3d_memory(ScrnInfoPtr pScrn)
{
- 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 (pI830->TripleBuffer && !I830AllocateThirdBuffer(pScrn, flags))
- return FALSE;
-
- if (!I830AllocateDepthBuffer(pScrn, flags))
- return FALSE;
++ I830Ptr pI830 = I830PTR(pScrn);
+
- if (!I830AllocateTextureMemory(pScrn, flags))
- return FALSE;
+ DPRINTF(PFX, "i830_allocate_3d_memory\n");
- return TRUE;
- }
- #endif
+ if (!i830_allocate_backbuffer(pScrn))
+ return FALSE;
- /* Allocate pool space that isn't pre-allocated */
- Bool
- I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool)
- {
- I830Ptr pI830 = I830PTR(pScrn);
++ if (pI830->TripleBuffer && !i830_allocate_thirdbuffer(pScrn)) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Failed to allocate third buffer, triple buffering "
++ "inactive\n");
++ }
+
- DPRINTF(PFX, "I830DoPoolAllocation\n");
+ if (!i830_allocate_depthbuffer(pScrn))
+ return FALSE;
- if (!pool)
- return FALSE;
+ if (!i830_allocate_texture_memory(pScrn))
+ return FALSE;
- /*
- * Sanity check: there shouldn't be an allocation required when
- * there is only stolen memory.
- */
- if (pI830->StolenOnly && (pool->Total.Size > pool->Fixed.Size)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "I830DoPoolAllocation(): pool size is greater than the "
- "preallocated size,\n\t"
- "and there is no allocatable memory.\n");
- return FALSE;
- }
-
- 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);
- if (pool->Allocated.Key == -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n");
- return FALSE;
- }
- pool->Allocated.Start = pool->Fixed.End;
- pool->Allocated.End = pool->Total.Size;
- pool->Allocated.Offset = pool->Allocated.Start;
- } else
- pool->Allocated.Key = -1;
- return TRUE;
+ return TRUE;
}
+ #endif
- static unsigned long topOfMem = 0;
-
- /*
- * These modify the way memory is positioned within the aperture.
- *
- * By default, memory allocated from the bottom or specifically within
- * the pool at the bottom gets allocated from the "stolen pool", which is
- * actually the stolen memory plus any extra allocated to make it a larger
- * contiguous region. Memory allocated from the AGP is allocated top-down
- * from the end of the aperture space. Memory allocated "from top" defaults
- * to AGP if there is enough "free space". The total allocation (stolen +
- * extra) doesn't exceed the orignal pScrn->videoRam amount (this isn't true
- * when memory allocated from AGP gets moved into the pool by one of the
- * following options.
- *
- * XXX Write a better description.
+ #ifdef XF86DRI
+ /**
+ * Sets up a fence area for the hardware.
*
+ * The fences control automatic tiled address swizzling for CPU access of the
+ * framebuffer.
*/
- #define PACK_RANGES 0
- #define POOL_RANGES 0
+ static void
+ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset,
+ unsigned int pitch, unsigned int size,
+ enum tile_format tile_format)
+ {
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 val;
+ CARD32 fence_mask = 0;
+ unsigned int fence_pitch;
- Bool
- I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem)
- {
- #if POOL_RANGES
- I830Ptr pI830 = I830PTR(pScrn);
- #endif
+ DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n",
+ nr, offset, pitch, size / 1024);
- if (!mem)
- return FALSE;
+ assert(tile_format != TILING_NONE);
- if (mem->Pool && mem->Key == -1 && mem->Start < 0) {
- mem->Start = mem->Pool->Total.End + mem->Start;
- mem->End = mem->Start + mem->Size;
- }
- #if PACK_RANGES
- /*
- * Map AGP-allocated areas at the top of the stolen area, resulting in
- * a contiguous region in the aperture. Normally most AGP-allocated areas
- * will be at the top of the aperture, making alignment requirements
- * easier to achieve. This optin is primarily for debugging purposes,
- * and using this option can break any special alignment requirements.
- */
- if (!mem->Pool && mem->Start != 0 && mem->Key != -1 && mem->Physical == 0 &&
- mem->Offset != 0) {
- long diff;
- if (mem->Offset != mem->Start)
- ErrorF("mem %p, Offset != Start\n", mem);
- diff = mem->Offset - topOfMem;
- mem->Start -= diff;
- mem->End -= diff;
- mem->Offset -= diff;
- topOfMem += mem->Size;
- }
- #elif POOL_RANGES
- /*
- * Move AGP-allocated regions (that don't need a physical address) into
- * the pre-allocated pool when there's enough space to do so. Note: the
- * AGP-allocated areas aren't freed. This option is primarily for
- * debugging purposes, and using it can break any special alignment
- * requirements.
- */
- if (!mem->Pool && mem->Start >= pI830->StolenPool.Free.End &&
- mem->Key != -1 && mem->Physical == 0 && mem->Offset != 0 &&
- pI830->StolenPool.Free.Size >= mem->Size) {
- long diff;
- if (mem->Offset != mem->Start)
- ErrorF("mem %p, Offset != Start\n", mem);
- diff = mem->Offset - pI830->StolenPool.Free.Start;
- mem->Start -= diff;
- mem->End -= diff;
- mem->Offset -= diff;
- mem->Key = -1;
- pI830->StolenPool.Free.Start += mem->Size;
- pI830->StolenPool.Free.Size -= mem->Size;
- }
- #endif
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "%p: Memory at offset 0x%08lx, size %ld kBytes\n", (void *)mem,
- mem->Start, mem->Size / 1024);
- return TRUE;
- }
+ if (IS_I965G(pI830)) {
+ if (nr < 0 || nr >= FENCE_NEW_NR) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): fence %d out of range\n",nr);
+ return;
+ }
+
+ switch (tile_format) {
+ case TILING_XMAJOR:
+ pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1;
+ pI830->fence[nr] |= I965_FENCE_X_MAJOR;
+ break;
+ case TILING_YMAJOR:
+ /* YMajor can be 128B aligned but the current code dictates
+ * otherwise. This isn't a problem apart from memory waste.
+ * FIXME */
+ pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1;
+ pI830->fence[nr] |= I965_FENCE_Y_MAJOR;
+ break;
+ case TILING_NONE:
+ break;
+ }
- Bool
- I830FixupOffsets(ScrnInfoPtr pScrn)
- {
- I830Ptr pI830 = I830PTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int i;
-
- DPRINTF(PFX, "I830FixupOffsets\n");
-
- topOfMem = pI830->StolenPool.Total.End;
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- I830FixOffset(pScrn, &(pI830->FrontBuffer2));
- I830FixOffset(pScrn, &(pI830->FrontBuffer));
-
- for (i = 0; i < xf86_config->num_crtc; i++) {
- I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
-
- I830FixOffset(pScrn, &intel_crtc->cursor_mem);
- I830FixOffset(pScrn, &intel_crtc->cursor_mem_argb);
- }
-
- I830FixOffset(pScrn, &(pI830->LpRing->mem));
- I830FixOffset(pScrn, &(pI830->Scratch));
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- I830FixOffset(pScrn, &(pI830->Scratch2));
- #ifdef I830_XV
- if (pI830->XvEnabled) {
- I830FixOffset(pScrn, pI830->OverlayMem);
- if (pI830->LinearAlloc)
- I830FixOffset(pScrn, &(pI830->LinearMem));
- }
- #endif
- #ifdef XF86DRI
- if (pI830->directRenderingEnabled) {
- I830FixOffset(pScrn, &(pI830->ContextMem));
- I830FixOffset(pScrn, &(pI830->BackBuffer));
- I830FixOffset(pScrn, &(pI830->ThirdBuffer));
- I830FixOffset(pScrn, &(pI830->DepthBuffer));
- if (pI830->mmModeFlags & I830_KERNEL_TEX) {
- I830FixOffset(pScrn, &(pI830->TexMem));
- }
- }
- #endif
- #ifdef I830_USE_EXA
- if (pI830->useEXA) {
- I830FixOffset(pScrn, &(pI830->Offscreen));
- if (IS_I965G(pI830))
- I830FixOffset(pScrn, &(pI830->EXAStateMem));
+ /* The end marker is the address of the last page in the allocation. */
+ pI830->fence[FENCE_NEW_NR + nr] = offset + size - 4096;
+ return;
}
- #endif
- return TRUE;
- }
- #ifdef XF86DRI
- /* Tiled memory is good... really, really good...
- *
- * Need to make it less likely that we miss out on this - probably
- * need to move the frontbuffer away from the 'guarenteed' alignment
- * of the first memory segment, or perhaps allocate a discontigous
- * framebuffer to get more alignment 'sweet spots'.
- */
- static void
- SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
- unsigned int size)
- {
- I830Ptr pI830 = I830PTR(pScrn);
- I830RegPtr i830Reg = &pI830->ModeReg;
- CARD32 val;
- CARD32 fence_mask = 0;
- unsigned int fence_pitch;
-
- DPRINTF(PFX, "SetFence: %d, 0x%08x, %d, %d kByte\n",
- nr, start, pitch, size / 1024);
-
- if (nr < 0 || nr > 7) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: fence %d out of range\n",nr);
- return;
- }
+ if (nr < 0 || nr >= FENCE_NR) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): fence %d out of range\n",nr);
+ return;
+ }
- i830Reg->Fence[nr] = 0;
+ pI830->fence[nr] = 0;
- if (IS_I9XX(pI830))
+ if (IS_I9XX(pI830))
fence_mask = ~I915G_FENCE_START_MASK;
- else
+ else
fence_mask = ~I830_FENCE_START_MASK;
- if (start & fence_mask) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: start (0x%08x) is not %s aligned\n",
- nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k");
- return;
- }
-
- if (start % size) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n",
- nr, start, size / 1024);
- return;
- }
-
- if (pitch & 127) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n",
- nr, pitch);
- return;
- }
+ if (offset & fence_mask) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): %d: offset (0x%08x) is not %s aligned\n",
+ nr, offset, (IS_I9XX(pI830)) ? "1MB" : "512k");
+ return;
+ }
+
+ if (offset % size) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): %d: offset (0x%08x) is not size (%dk) "
+ "aligned\n",
+ nr, offset, size / 1024);
+ return;
+ }
+
+ if (pitch & 127) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): %d: pitch (%d) not a multiple of 128 "
+ "bytes\n",
+ nr, pitch);
+ return;
+ }
+
+ val = offset | FENCE_VALID;
- val = (start | FENCE_X_MAJOR | FENCE_VALID);
+ switch (tile_format) {
+ case TILING_XMAJOR:
+ val |= FENCE_X_MAJOR;
+ break;
+ case TILING_YMAJOR:
+ val |= FENCE_Y_MAJOR;
+ break;
+ case TILING_NONE:
+ break;
+ }
- if (IS_I9XX(pI830)) {
+ if (IS_I9XX(pI830)) {
switch (size) {
- case MB(1):
- val |= I915G_FENCE_SIZE_1M;
- break;
- case MB(2):
- val |= I915G_FENCE_SIZE_2M;
- break;
- case MB(4):
- val |= I915G_FENCE_SIZE_4M;
- break;
- case MB(8):
- val |= I915G_FENCE_SIZE_8M;
- break;
- case MB(16):
- val |= I915G_FENCE_SIZE_16M;
- break;
- case MB(32):
- val |= I915G_FENCE_SIZE_32M;
- break;
- case MB(64):
- val |= I915G_FENCE_SIZE_64M;
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
- return;
+ case MB(1):
+ val |= I915G_FENCE_SIZE_1M;
+ break;
+ case MB(2):
+ val |= I915G_FENCE_SIZE_2M;
+ break;
+ case MB(4):
+ val |= I915G_FENCE_SIZE_4M;
+ break;
+ case MB(8):
+ val |= I915G_FENCE_SIZE_8M;
+ break;
+ case MB(16):
+ val |= I915G_FENCE_SIZE_16M;
+ break;
+ case MB(32):
+ val |= I915G_FENCE_SIZE_32M;
+ break;
+ case MB(64):
+ val |= I915G_FENCE_SIZE_64M;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "i830_set_fence(): %d: illegal size (%d kByte)\n",
+ nr, size / 1024);
+ return;
}
} else {
switch (size) {
diff --cc src/i830_xaa.c
index 9b11973,9ecf706..46ea7ec
@@@ -279,13 -279,17 +279,22 @@@
if (IS_I965G(pI830)) {
if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR)
tiled = 1;
- if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR)
+ if (pI830->back_buffer != NULL &&
+ pI830->bufferOffset == pI830->back_buffer->offset &&
+ pI830->back_tiled == FENCE_XMAJOR) {
tiled = 1;
- if (pI830->bufferOffset == pI830->ThirdBuffer.Start && pI830->third_tiled == FENCE_XMAJOR)
+ }
++ if (pI830->third_buffer != NULL &&
++ pI830->bufferOffset == pI830->third_buffer->offset &&
++ pI830->third_tiled == FENCE_XMAJOR) {
+ tiled = 1;
++ }
/* not really supported as it's always YMajor tiled */
- if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR)
+ if (pI830->depth_buffer != NULL &&
+ pI830->bufferOffset == pI830->depth_buffer->offset &&
+ pI830->depth_tiled == FENCE_XMAJOR) {
tiled = 1;
+ }
}
return tiled;
diff-tree 50ba1fff886a7f51b178ac6d3a1ba79a3014b214 (from 36cad3fcb65e3dcd88e58e301cd60adb121cb96b)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Mon Mar 5 10:22:07 2007 +0100
Be more verbose when page flipping can't be enabled for various reasons.
diff --git a/src/i830_dri.c b/src/i830_dri.c
index e546066..dba1a07 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1146,7 +1146,7 @@ I830DRISwapContext(ScreenPtr pScreen, DR
if (pI830->pDamage == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"No screen damage record, page flipping disabled\n");
- pI830->allowPageFlip = 0;
+ pI830->allowPageFlip = FALSE;
} else {
DamageRegister(&pPix->drawable, pI830->pDamage);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 9bd7029..c950149 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -853,7 +853,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
int i;
char *s;
pointer pVBEModule = NULL;
- Bool enable;
const char *chipname;
int num_pipe;
int max_width, max_height;
@@ -1479,14 +1478,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
pI830->colorKey);
#endif
- pI830->allowPageFlip = FALSE;
- enable = xf86ReturnOptValBool(pI830->Options, OPTION_PAGEFLIP, FALSE);
#ifdef XF86DRI
- if (!pI830->directRenderingDisabled) {
- pI830->allowPageFlip = enable;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "page flipping %s\n",
- enable ? "enabled" : "disabled");
- }
+ pI830->allowPageFlip = FALSE;
+ from = (!pI830->directRenderingDisabled &&
+ xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP,
+ &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT;
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n",
+ pI830->allowPageFlip ? "" : " not");
#endif
#ifdef XF86DRI
@@ -1676,6 +1675,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
-pI830->MemoryAperture.Size / 1024);
}
pScrn->displayWidth = savedDisplayWidth;
+ if (pI830->allowPageFlip)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Can't enable page flipping due to the above\n");
pI830->allowPageFlip = FALSE;
} else if (pScrn->displayWidth != savedDisplayWidth) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -2682,6 +2684,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr
I830SetupMemoryTiling(pScrn);
pI830->directRenderingEnabled = I830DRIDoMappings(pScreen);
}
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page Flipping %sabled\n",
+ pI830->allowPageFlip ? "en" : "dis");
#endif
DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n");
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 2d1cca9..a952b70 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1762,6 +1762,9 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"I830SetupMemoryTiling: Not tileable 0x%x\n",
pScrn->displayWidth * pI830->cpp);
+ if (pI830->allowPageFlip)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Can't enable page flipping due to the above\n");
pI830->allowPageFlip = FALSE;
return;
}
@@ -1778,14 +1781,20 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
"Activating tiled memory for the front buffer\n");
pI830->front_tiled = FENCE_XMAJOR;
} else {
- pI830->allowPageFlip = FALSE;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"MakeTiles failed for the front buffer\n");
+ if (pI830->allowPageFlip)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Can't enable page flipping due to the above\n");
+ pI830->allowPageFlip = FALSE;
}
} else {
- pI830->allowPageFlip = FALSE;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Alignment bad for the front buffer\n");
+ if (pI830->allowPageFlip)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Can't enable page flipping due to the above\n");
+ pI830->allowPageFlip = FALSE;
}
}
@@ -1803,6 +1812,9 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"MakeTiles failed for the back buffer.\n");
+ if (pI830->allowPageFlip)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Can't enable page flipping due to the above\n");
pI830->allowPageFlip = FALSE;
}
}
@@ -1815,6 +1827,9 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"MakeTiles failed for the third buffer.\n");
+ if (pI830->allowPageFlip)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Can't enable page flipping due to the above\n");
pI830->allowPageFlip = FALSE;
}
}
diff-tree 36cad3fcb65e3dcd88e58e301cd60adb121cb96b (from b5316fb2623e9630cbd58020e0a7c95bf354c587)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Wed Feb 28 17:52:42 2007 +0100
Update vblank pipe setup when setting a mode.
diff --git a/src/i830_display.c b/src/i830_display.c
index 258897e..04159e7 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -864,6 +864,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
OUTREG(dspcntr_reg, dspcntr);
/* Flush the plane changes */
i830PipeSetBase(crtc, x, y);
+#ifdef XF86DRI
+ I830DRISetVBlankInterrupt (pScrn, TRUE);
+#endif
i830WaitForVblank(pScrn);
}
@@ -1041,9 +1044,6 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayMo
i830DescribeOutputConfiguration(pScrn);
-#ifdef XF86DRI
- I830DRISetVBlankInterrupt (pScrn, TRUE);
-#endif
done:
i830DumpRegs (pScrn);
i830_sdvo_dump(pScrn);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 3c8ec1a..9bd7029 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3085,10 +3085,6 @@ I830EnterVT(int scrnIndex, int flags)
i830DumpRegs (pScrn);
i830DescribeOutputConfiguration(pScrn);
-#ifdef XF86DRI
- I830DRISetVBlankInterrupt (pScrn, TRUE);
-#endif
-
ResetState(pScrn, TRUE);
SetHWOperatingState(pScrn);
diff-tree b5316fb2623e9630cbd58020e0a7c95bf354c587 (from f5ab9e0ad3a65c972861dd53be6e33e1aac13191)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Wed Feb 28 17:50:56 2007 +0100
I830DRIClipNotify: Fix initialization of crtcBox[1].[xy]2.
diff --git a/src/i830_dri.c b/src/i830_dri.c
index afc7de0..e546066 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1523,8 +1523,8 @@ I830DRIClipNotify(ScreenPtr pScreen, Win
crtcBox[0].y2 = crtcBox[0].y1 + sPriv->pipeA_h;
crtcBox[1].x1 = sPriv->pipeB_x;
crtcBox[1].y1 = sPriv->pipeB_y;
- crtcBox[1].x2 = crtcBox[0].x1 + sPriv->pipeB_w;
- crtcBox[1].y2 = crtcBox[0].y1 + sPriv->pipeB_h;
+ crtcBox[1].x2 = crtcBox[1].x1 + sPriv->pipeB_w;
+ crtcBox[1].y2 = crtcBox[1].y1 + sPriv->pipeB_h;
for (i = 0; i < 2; i++) {
for (j = 0; j < num; j++) {
diff-tree f5ab9e0ad3a65c972861dd53be6e33e1aac13191 (from 8cce74f195e5ef6ce5599ecd52f35bcfcb0d7913)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Feb 22 18:57:23 2007 +0100
I830DRISwapContext: Some cleanups.
Also call I830EmitFlush() when entering/leaving the server context. Doesn't
seem to help for artifacts with page flipping and mixed 2D/3D unfortunately.
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 6c91cdc..afc7de0 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1135,6 +1135,8 @@ I830DRISwapContext(ScreenPtr pScreen, DR
pI830->LockHeld = 1;
I830RefreshRing(pScrn);
+ I830EmitFlush(pScrn);
+
#ifdef DAMAGE
if (!pI830->pDamage && pI830->allowPageFlip) {
PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
@@ -1159,10 +1161,12 @@ I830DRISwapContext(ScreenPtr pScreen, DR
} else if (syncType == DRI_2D_SYNC &&
oldContextType == DRI_NO_CONTEXT &&
newContextType == DRI_2D_CONTEXT) {
- pI830->LockHeld = 0;
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (out)\n");
+ if (!pScrn->vtSema)
+ return;
+
#ifdef DAMAGE
if (pI830->pDamage) {
RegionPtr pDamageReg = DamageRegion(pI830->pDamage);
@@ -1181,6 +1185,10 @@ I830DRISwapContext(ScreenPtr pScreen, DR
}
}
#endif
+
+ I830EmitFlush(pScrn);
+
+ pI830->LockHeld = 0;
} else if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (other)\n");
}
diff-tree 8cce74f195e5ef6ce5599ecd52f35bcfcb0d7913 (from f346549183a407a4bff6521ec2450dacb97442e9)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Feb 22 18:27:59 2007 +0100
Do not sync DRI windows between pages when possible.
diff --git a/src/i830.h b/src/i830.h
index bbbb4a8..e26556f 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -310,6 +310,7 @@ typedef struct _I830Rec {
#ifdef DAMAGE
DamagePtr pDamage;
+ RegionRec driRegion;
#endif
#endif
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 65736cd..6c91cdc 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -980,6 +980,10 @@ I830DRICloseScreen(ScreenPtr pScreen)
DPRINTF(PFX, "I830DRICloseScreen\n");
+#ifdef DAMAGE
+ REGION_UNINIT(pScreen, &pI830->driRegion);
+#endif
+
if (pI830DRI->irq) {
drmCtlUninstHandler(pI830->drmSubFD);
pI830DRI->irq = 0;
@@ -1164,10 +1168,16 @@ I830DRISwapContext(ScreenPtr pScreen, DR
RegionPtr pDamageReg = DamageRegion(pI830->pDamage);
if (pDamageReg) {
- int nrects = REGION_NUM_RECTS(pDamageReg);
+ RegionRec region;
+ int nrects;
- if (nrects)
- I830DRIRefreshArea(pScrn, nrects, REGION_RECTS(pDamageReg));
+ REGION_NULL(pScreen, ®ion);
+ REGION_SUBTRACT(pScreen, ®ion, pDamageReg, &pI830->driRegion);
+
+ if ((nrects = REGION_NUM_RECTS(®ion)))
+ I830DRIRefreshArea(pScrn, nrects, REGION_RECTS(®ion));
+
+ REGION_UNINIT(pScreen, ®ion);
}
}
#endif
@@ -1486,8 +1496,13 @@ I830DRITransitionTo2d(ScreenPtr pScreen)
static void
I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
unsigned pfMask = 0;
+ REGION_UNINIT(pScreen, &pI830->driRegion);
+ REGION_NULL(pScreen, &pI830->driRegion);
+
if (num > 0) {
drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
BoxRec crtcBox[2];
@@ -1505,15 +1520,24 @@ I830DRIClipNotify(ScreenPtr pScreen, Win
for (i = 0; i < 2; i++) {
for (j = 0; j < num; j++) {
- if (ppWin[j] && RECT_IN_REGION(pScreen, &ppWin[j]->clipList,
- &crtcBox[i]) != rgnOUT)
- numvisible[i]++;
+ WindowPtr pWin = ppWin[j];
+
+ if (pWin) {
+ if (RECT_IN_REGION(pScreen, &pWin->clipList, &crtcBox[i]) !=
+ rgnOUT)
+ numvisible[i]++;
+
+ if (i == 0)
+ REGION_UNION(pScreen, &pI830->driRegion, &pWin->clipList,
+ &pI830->driRegion);
+ }
}
if (numvisible[i] == 1)
pfMask |= 1 << i;
}
- }
+ } else
+ REGION_NULL(pScreen, &pI830->driRegion);
I830DRISetPfMask(pScreen, pfMask);
}
diff-tree f346549183a407a4bff6521ec2450dacb97442e9 (from 0bee64f4bc7581de7ab28ca438581d215e85c610)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Wed Feb 21 09:19:54 2007 +0100
intel.man: Fix typo.
diff --git a/man/intel.man b/man/intel.man
index 503b52a..05a91f7 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -170,7 +170,7 @@ Default for i810: The option is not used
Default for i830 and above: Disabled.
.TP
.BI "Option \*qTripleBuffer\*q \*q" boolean \*q
-Enable support for triple flipping. This should improve 3D performance at the
+Enable support for triple buffering. This should improve 3D performance at the
potential cost of worse performance with mixed 2D/3D. Also note that this gives
no benefit without corresponding support in the Mesa 3D driver and may not give
any benefit without page flipping either (see
diff-tree 0bee64f4bc7581de7ab28ca438581d215e85c610 (from 2212baa8454abb4c7948c3f2e20e337f831d1b86)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Tue Feb 20 19:09:37 2007 +0100
Add support for triple buffering using a third static buffer.
Need to bump the DRI DDX version minor for the added SAREA fields.
diff --git a/man/intel.man b/man/intel.man
index 3f4cff8..503b52a 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -162,9 +162,22 @@ Default: 32768.
.BI "Option \*qPageFlip\*q \*q" boolean \*q
Enable support for page flipping. This should improve 3D performance at the
potential cost of worse performance or artifacts with mixed 2D/3D. Also note
-that this gives no benefit without corresponding support in the Mesa 3D driver.
+that this gives no benefit without corresponding support in the Mesa 3D driver
+and may not give the full benefit without triple buffering (see
+.B "Option \*qTripleBuffer\*q"
+).
Default for i810: The option is not used.
-Default for i9xx: Disabled.
+Default for i830 and above: Disabled.
+.TP
+.BI "Option \*qTripleBuffer\*q \*q" boolean \*q
+Enable support for triple flipping. This should improve 3D performance at the
+potential cost of worse performance with mixed 2D/3D. Also note that this gives
+no benefit without corresponding support in the Mesa 3D driver and may not give
+any benefit without page flipping either (see
+.B "Option \*qPageFlip\*q"
+).
+Default for i810: The option is not used.
+Default for i830 and above: Disabled.
.TP
.BI "Option \*qAccelMethod\*q \*q" string \*q
Choose acceleration architecture, either "XAA" or "EXA". XAA is the old
diff --git a/src/i830.h b/src/i830.h
index 78381fb..bbbb4a8 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -294,6 +294,7 @@ typedef struct _I830Rec {
I830MemRange ContextMem;
#ifdef XF86DRI
I830MemRange BackBuffer;
+ I830MemRange ThirdBuffer;
I830MemRange DepthBuffer;
I830MemRange TexMem;
int TexGranularity;
@@ -304,6 +305,7 @@ typedef struct _I830Rec {
unsigned int front_tiled;
unsigned int back_tiled;
+ unsigned int third_tiled;
unsigned int depth_tiled;
#ifdef DAMAGE
@@ -313,6 +315,7 @@ typedef struct _I830Rec {
Bool NeedRingBufferLow;
Bool allowPageFlip;
+ Bool TripleBuffer;
Bool disableTiling;
int backPitch;
@@ -511,6 +514,7 @@ typedef struct _I830Rec {
#define I830_SELECT_FRONT 0
#define I830_SELECT_BACK 1
#define I830_SELECT_DEPTH 2
+#define I830_SELECT_THIRD 3
/* I830 specific functions */
extern int I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis);
@@ -539,6 +543,7 @@ extern void i830_crtc_dpms_video(xf86Crt
#ifdef XF86DRI
extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags);
extern Bool I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags);
+extern Bool I830AllocateThirdBuffer(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);
diff --git a/src/i830_accel.c b/src/i830_accel.c
index db3168a..c76c748 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -228,6 +228,9 @@ I830SelectBuffer(ScrnInfoPtr pScrn, int
case I830_SELECT_BACK:
pI830->bufferOffset = pI830->BackBuffer.Start;
break;
+ case I830_SELECT_THIRD:
+ pI830->bufferOffset = pI830->ThirdBuffer.Start;
+ break;
case I830_SELECT_DEPTH:
pI830->bufferOffset = pI830->DepthBuffer.Start;
break;
diff --git a/src/i830_common.h b/src/i830_common.h
index 79455b6..f853ccd 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -130,6 +130,12 @@ typedef struct {
int pipeB_y;
int pipeB_w;
int pipeB_h;
+
+ /* Triple buffering */
+ drm_handle_t third_handle;
+ int third_offset;
+ int third_size;
+ unsigned int third_tiled;
} drmI830Sarea;
/* Flags for perf_boxes
diff --git a/src/i830_dri.c b/src/i830_dri.c
index d655183..65736cd 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -751,6 +751,20 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScr
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Back Buffer = 0x%08x\n",
(int)sarea->back_handle);
+ if (pI830->TripleBuffer) {
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(sarea->third_offset + pI830->LinearAddr),
+ sarea->third_size, DRM_AGP, 0,
+ (drmAddress) &sarea->third_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(third_handle) failed. Disabling DRI\n");
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Third Buffer = 0x%08x\n",
+ (int)sarea->third_handle);
+ }
+
if (drmAddMap(pI830->drmSubFD,
(drm_handle_t)sarea->depth_offset + pI830->LinearAddr,
sarea->depth_size, DRM_AGP, 0,
@@ -794,6 +808,10 @@ I830DRIUnmapScreenRegions(ScrnInfoPtr pS
drmRmMap(pI830->drmSubFD, sarea->back_handle);
sarea->back_handle = 0;
}
+ if (sarea->third_handle) {
+ drmRmMap(pI830->drmSubFD, sarea->third_handle);
+ sarea->third_handle = 0;
+ }
if (sarea->depth_handle) {
drmRmMap(pI830->drmSubFD, sarea->depth_handle);
sarea->depth_handle = 0;
@@ -870,6 +888,7 @@ I830DRIDoMappings(ScreenPtr pScreen)
/* init to zero to be safe */
sarea->front_handle = 0;
sarea->back_handle = 0;
+ sarea->third_handle = 0;
sarea->depth_handle = 0;
sarea->tex_handle = 0;
@@ -1041,17 +1060,10 @@ I830DRIFinishScreenInit(ScreenPtr pScree
* Otherwise will have to sync again???
*/
static void
-I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+I830DRIDoRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox, CARD32 dst)
{
I830Ptr pI830 = I830PTR(pScrn);
int i, cmd, br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
- drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
-
- /* Don't want to do this when no 3d is active and pages are
- * right-way-round :
- */
- if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0)
- return;
if (pScrn->bitsPerPixel == 32) {
cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
@@ -1068,12 +1080,31 @@ I830DRIRefreshArea (ScrnInfoPtr pScrn, i
OUT_RING(br13);
OUT_RING((pbox->y1 << 16) | pbox->x1);
OUT_RING((pbox->y2 << 16) | pbox->x2);
- OUT_RING(pI830->BackBuffer.Start);
+ OUT_RING(dst);
OUT_RING((pbox->y1 << 16) | pbox->x1);
OUT_RING(br13 & 0xffff);
OUT_RING(pI830->FrontBuffer.Start);
ADVANCE_LP_RING();
}
+}
+
+static void
+I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+
+ /* Don't want to do this when no 3d is active and pages are
+ * right-way-round :
+ */
+ if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0)
+ return;
+
+ I830DRIDoRefreshArea(pScrn, num, pbox, pI830->BackBuffer.Start);
+
+ if (pI830->TripleBuffer) {
+ I830DRIDoRefreshArea(pScrn, num, pbox, pI830->ThirdBuffer.Start);
+ }
DamageEmpty(pI830->pDamage);
}
@@ -1160,6 +1191,13 @@ I830DRIInitBuffers(WindowPtr pWin, Regio
I830SelectBuffer(pScrn, I830_SELECT_BACK);
I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+
+ if (I830PTR(pScrn)->TripleBuffer) {
+ I830SelectBuffer(pScrn, I830_SELECT_THIRD);
+ I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+
pbox++;
}
@@ -1333,6 +1371,10 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
I830SelectBuffer(pScrn, I830_SELECT_BACK);
I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
+ if (pI830->TripleBuffer) {
+ I830SelectBuffer(pScrn, I830_SELECT_THIRD);
+ I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
+ }
if (!IS_I965G(pI830)) {
I830SelectBuffer(pScrn, I830_SELECT_DEPTH);
I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
@@ -1492,6 +1534,7 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn,
sarea->front_tiled = pI830->front_tiled;
sarea->back_tiled = pI830->back_tiled;
+ sarea->third_tiled = pI830->third_tiled;
sarea->depth_tiled = pI830->depth_tiled;
sarea->rotated_tiled = FALSE;
@@ -1509,6 +1552,8 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn,
sarea->height = pScreen->height;
sarea->back_offset = pI830->BackBuffer.Start;
sarea->back_size = pI830->BackBuffer.Size;
+ sarea->third_offset = pI830->ThirdBuffer.Start;
+ sarea->third_size = pI830->ThirdBuffer.Size;
sarea->depth_offset = pI830->DepthBuffer.Start;
sarea->depth_size = pI830->DepthBuffer.Size;
sarea->tex_offset = pI830->TexMem.Start;
diff --git a/src/i830_dri.h b/src/i830_dri.h
index a140497..a2cf78e 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 7
-#define I830_PATCHLEVEL 2
+#define I830_MINOR_VERSION 8
+#define I830_PATCHLEVEL 0
#define I830_REG_SIZE 0x80000
diff --git a/src/i830_driver.c b/src/i830_driver.c
index d1f83e5..3c8ec1a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -273,7 +273,8 @@ typedef enum {
OPTION_CHECKDEVICES,
OPTION_LINEARALLOC,
OPTION_INTELTEXPOOL,
- OPTION_INTELMMSIZE
+ OPTION_INTELMMSIZE,
+ OPTION_TRIPLEBUFFER,
} I830Opts;
static OptionInfoRec I830Options[] = {
@@ -292,6 +293,7 @@ static OptionInfoRec I830Options[] = {
{OPTION_LINEARALLOC, "LinearAlloc", OPTV_INTEGER, {0}, FALSE},
{OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_INTELMMSIZE, "AperTexSize", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
/* *INDENT-ON* */
@@ -1487,6 +1489,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
}
#endif
+#ifdef XF86DRI
+ pI830->TripleBuffer = FALSE;
+ from = (!pI830->directRenderingDisabled &&
+ xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER,
+ &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT;
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n",
+ pI830->TripleBuffer ? "en" : "dis");
+#endif
+
/*
* If the driver can do gamma correction, it should call xf86SetGamma() here.
*/
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 29d9d31..2d1cca9 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1118,6 +1118,69 @@ I830AllocateBackBuffer(ScrnInfoPtr pScrn
}
Bool
+I830AllocateThirdBuffer(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;
+
+ /* Third Buffer */
+ memset(&(pI830->ThirdBuffer), 0, sizeof(pI830->ThirdBuffer));
+ pI830->ThirdBuffer.Key = -1;
+ tileable = !(flags & ALLOC_NO_TILING) &&
+ IsTileable(pScrn, 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 >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
+ alloced = I830AllocVidMem(pScrn, &(pI830->ThirdBuffer),
+ &(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->ThirdBuffer),
+ &(pI830->StolenPool), size, align,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
+ }
+ if (alloced < size) {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate third buffer space.\n");
+ }
+ return FALSE;
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocated %ld kB for the third buffer at 0x%lx.\n", s,
+ alloced / 1024, pI830->ThirdBuffer.Start);
+
+ return TRUE;
+}
+
+Bool
I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags)
{
I830Ptr pI830 = I830PTR(pScrn);
@@ -1271,6 +1334,9 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn,
if (!I830AllocateBackBuffer(pScrn, flags))
return FALSE;
+ if (pI830->TripleBuffer && !I830AllocateThirdBuffer(pScrn, flags))
+ return FALSE;
+
if (!I830AllocateDepthBuffer(pScrn, flags))
return FALSE;
@@ -1439,6 +1505,7 @@ I830FixupOffsets(ScrnInfoPtr pScrn)
if (pI830->directRenderingEnabled) {
I830FixOffset(pScrn, &(pI830->ContextMem));
I830FixOffset(pScrn, &(pI830->BackBuffer));
+ I830FixOffset(pScrn, &(pI830->ThirdBuffer));
I830FixOffset(pScrn, &(pI830->DepthBuffer));
if (pI830->mmModeFlags & I830_KERNEL_TEX) {
I830FixOffset(pScrn, &(pI830->TexMem));
@@ -1701,6 +1768,7 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
pI830->front_tiled = FENCE_LINEAR;
pI830->back_tiled = FENCE_LINEAR;
+ pI830->third_tiled = FENCE_LINEAR;
pI830->depth_tiled = FENCE_LINEAR;
if (pI830->allowPageFlip) {
@@ -1739,6 +1807,18 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
}
}
+ if (pI830->ThirdBuffer.Alignment >= KB(512)) {
+ if (MakeTiles(pScrn, &(pI830->ThirdBuffer), FENCE_XMAJOR)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Activating tiled memory for the third buffer.\n");
+ pI830->third_tiled = FENCE_XMAJOR;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "MakeTiles failed for the third buffer.\n");
+ pI830->allowPageFlip = FALSE;
+ }
+ }
+
if (pI830->DepthBuffer.Alignment >= KB(512)) {
if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -1825,6 +1905,8 @@ I830BindAGPMemory(ScrnInfoPtr pScrn)
return FALSE;
if (!BindMemRange(pScrn, &(pI830->BackBuffer)))
return FALSE;
+ if (pI830->TripleBuffer && !BindMemRange(pScrn, &(pI830->ThirdBuffer)))
+ return FALSE;
if (!BindMemRange(pScrn, &(pI830->DepthBuffer)))
return FALSE;
if ((pI830->mmModeFlags & I830_KERNEL_TEX) &&
@@ -1919,6 +2001,8 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->BackBuffer)))
return FALSE;
+ if (pI830->TripleBuffer && !UnbindMemRange(pScrn, &(pI830->ThirdBuffer)))
+ return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer)))
return FALSE;
if ((pI830->mmModeFlags & I830_KERNEL_TEX) &&
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index 5ef5d3c..9b11973 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -281,6 +281,8 @@ CheckTiling(ScrnInfoPtr pScrn)
tiled = 1;
if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR)
tiled = 1;
+ if (pI830->bufferOffset == pI830->ThirdBuffer.Start && pI830->third_tiled == FENCE_XMAJOR)
+ tiled = 1;
/* not really supported as it's always YMajor tiled */
if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR)
tiled = 1;
diff-tree 2212baa8454abb4c7948c3f2e20e337f831d1b86 (from fac8f2eb49de22abd853ca75f3c985d4d94e3633)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Tue Feb 20 18:39:13 2007 +0100
Don't mark page flipping as active when it really isn't.
diff --git a/src/i830_dri.c b/src/i830_dri.c
index b368c99..d655183 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1382,8 +1382,11 @@ I830DRISetPfMask(ScreenPtr pScreen, int
I830Ptr pI830 = I830PTR(pScrn);
drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
- pSAREAPriv->pf_enabled = pI830->allowPageFlip;
- pSAREAPriv->pf_active = pfMask;
+ if (pI830->allowPageFlip && pfMask) {
+ pSAREAPriv->pf_enabled = pI830->allowPageFlip;
+ pSAREAPriv->pf_active = pfMask;
+ } else
+ pSAREAPriv->pf_enabled = pSAREAPriv->pf_active = 0;
}
static void
diff-tree fac8f2eb49de22abd853ca75f3c985d4d94e3633 (from 55c7b017ed718107b9b11467030addf225728b84)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Tue Feb 20 18:38:40 2007 +0100
Document Option "PageFlip".
diff --git a/man/intel.man b/man/intel.man
index b932632..3f4cff8 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -159,6 +159,13 @@ atctivate the legacy texture pool (see
gain some performance by increasing this value.
Default: 32768.
.TP
+.BI "Option \*qPageFlip\*q \*q" boolean \*q
+Enable support for page flipping. This should improve 3D performance at the
+potential cost of worse performance or artifacts with mixed 2D/3D. Also note
+that this gives no benefit without corresponding support in the Mesa 3D driver.
+Default for i810: The option is not used.
+Default for i9xx: Disabled.
+.TP
.BI "Option \*qAccelMethod\*q \*q" string \*q
Choose acceleration architecture, either "XAA" or "EXA". XAA is the old
(but stable) XFree86 based acceleration architecture. EXA is a newer and
diff-tree 55c7b017ed718107b9b11467030addf225728b84 (from 3bd8edb95fcbbb49e97a1a2bdd5c8eae4f83d3a8)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Wed Feb 14 16:45:22 2007 +0100
Use new DRI ClipNotify hook to track page flipping per CRTC when available.
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 05171d3..b368c99 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -107,6 +107,7 @@ static void I830DRITransitionTo2d(Screen
static void I830DRITransitionTo3d(ScreenPtr pScreen);
static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen);
static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen);
+static void I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num);
#if 0
static void I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
@@ -551,10 +552,31 @@ I830DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->InitBuffers = I830DRIInitBuffers;
pDRIInfo->MoveBuffers = I830DRIMoveBuffers;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
- pDRIInfo->TransitionTo2d = I830DRITransitionTo2d;
- pDRIInfo->TransitionTo3d = I830DRITransitionTo3d;
- pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d;
- pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d;
+
+#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1
+ {
+ int major, minor, patch;
+
+ DRIQueryVersion(&major, &minor, &patch);
+
+ if (minor >= 1)
+#endif
+#if DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1)
+ pDRIInfo->ClipNotify = I830DRIClipNotify;
+#endif
+ }
+
+#if DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1)
+ if (!pDRIInfo->ClipNotify)
+#endif
+ {
+ pDRIInfo->TransitionTo2d = I830DRITransitionTo2d;
+ pDRIInfo->TransitionTo3d = I830DRITransitionTo3d;
+ pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d;
+ pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d;
+ }
/* do driver-independent DRI screen initialization here */
if (!DRIScreenInit(pScreen, pDRIInfo, &pI830->drmSubFD)) {
@@ -1354,41 +1376,35 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
*/
static void
-I830EnablePageFlip(ScreenPtr pScreen)
+I830DRISetPfMask(ScreenPtr pScreen, int pfMask)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
pSAREAPriv->pf_enabled = pI830->allowPageFlip;
- pSAREAPriv->pf_active = pI830->allowPageFlip;
+ pSAREAPriv->pf_active = pfMask;
}
static void
-I830DisablePageFlip(ScreenPtr pScreen)
-{
- drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
-
- pSAREAPriv->pf_active = 0;
-}
-
-
-static void
I830DRITransitionSingleToMulti3d(ScreenPtr pScreen)
{
/* Tell the clients not to pageflip. How?
* -- Field in sarea, plus bumping the window counters.
* -- DRM needs to cope with Front-to-Back swapbuffers.
*/
- I830DisablePageFlip(pScreen);
+ I830DRISetPfMask(pScreen, 0);
}
static void
I830DRITransitionMultiToSingle3d(ScreenPtr pScreen)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+
/* Let the remaining 3d app start page flipping again.
*/
- I830EnablePageFlip(pScreen);
+ I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0);
}
static void
@@ -1397,7 +1413,7 @@ I830DRITransitionTo3d(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- I830EnablePageFlip(pScreen);
+ I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0);
pI830->have3DWindows = 1;
}
@@ -1417,11 +1433,46 @@ I830DRITransitionTo2d(ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_WARNING,
"[dri] %s: kernel failed to unflip buffers.\n", __func__);
- I830DisablePageFlip(pScreen);
+ I830DRISetPfMask(pScreen, 0);
pI830->have3DWindows = 0;
}
+static void
+I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num)
+{
+ unsigned pfMask = 0;
+
+ if (num > 0) {
+ drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
+ BoxRec crtcBox[2];
+ unsigned numvisible[2] = { 0, 0 };
+ int i, j;
+
+ crtcBox[0].x1 = sPriv->pipeA_x;
+ crtcBox[0].y1 = sPriv->pipeA_y;
+ crtcBox[0].x2 = crtcBox[0].x1 + sPriv->pipeA_w;
+ crtcBox[0].y2 = crtcBox[0].y1 + sPriv->pipeA_h;
+ crtcBox[1].x1 = sPriv->pipeB_x;
+ crtcBox[1].y1 = sPriv->pipeB_y;
+ crtcBox[1].x2 = crtcBox[0].x1 + sPriv->pipeB_w;
+ crtcBox[1].y2 = crtcBox[0].y1 + sPriv->pipeB_h;
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < num; j++) {
+ if (ppWin[j] && RECT_IN_REGION(pScreen, &ppWin[j]->clipList,
+ &crtcBox[i]) != rgnOUT)
+ numvisible[i]++;
+ }
+
+ if (numvisible[i] == 1)
+ pfMask |= 1 << i;
+ }
+ }
+
+ I830DRISetPfMask(pScreen, pfMask);
+}
+
/**
* Update the SAREA fields with the most recent values.
diff-tree 3bd8edb95fcbbb49e97a1a2bdd5c8eae4f83d3a8 (from 1d22bad33b634aaf61976907cb2ceeec8a9ebe4d)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Fri Feb 2 17:41:18 2007 +0100
Revive i830 page flipping support.
Use the damage layer directly instead of via shadowfb.
diff --git a/configure.ac b/configure.ac
index d45185a..219fbe6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -94,6 +94,8 @@ if test "$DRI" != no; then
[have_sarea_h="yes"], [have_sarea_h="no"])
AC_CHECK_FILE([${sdkdir}/dristruct.h],
[have_dristruct_h="yes"], [have_dristruct_h="no"])
+ AC_CHECK_FILE([${sdkdir}/damage.h],
+ [have_damage_h="yes"], [have_damage_h="no"])
fi
AC_MSG_CHECKING([whether to include DRI support])
@@ -127,6 +129,9 @@ if test "$DRI" = yes; then
if test "x$DRI_MM" = xyes; then
AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management])
fi
+ if test "$have_damage_h" = yes; then
+ AC_DEFINE(DAMAGE,1,[Use Damage extension])
+ fi
fi
AM_CONDITIONAL(VIDEO_DEBUG, test x$VIDEO_DEBUG = xyes)
diff --git a/src/i830.h b/src/i830.h
index 96972eb..78381fb 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -68,6 +68,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
#include "dri.h"
#include "GL/glxint.h"
#include "i830_dri.h"
+#ifdef DAMAGE
+#include "damage.h"
+#endif
#endif
#ifdef I830_USE_EXA
@@ -302,6 +305,10 @@ typedef struct _I830Rec {
unsigned int front_tiled;
unsigned int back_tiled;
unsigned int depth_tiled;
+
+#ifdef DAMAGE
+ DamagePtr pDamage;
+#endif
#endif
Bool NeedRingBufferLow;
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 3531bf5..05171d3 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -984,17 +984,6 @@ I830DRIFinishScreenInit(ScreenPtr pScree
DPRINTF(PFX, "I830DRIFinishScreenInit\n");
- /* Have shadow run only while there is 3d active.
- */
-#if 0
- if (pI830->allowPageFlip && pI830->drmMinor >= 1) {
- shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0);
- }
- else
-#endif
- pI830->allowPageFlip = 0;
-
-
if (!DRIFinishScreenInit(pScreen))
return FALSE;
@@ -1025,6 +1014,49 @@ I830DRIFinishScreenInit(ScreenPtr pScree
}
}
+#ifdef DAMAGE
+/* This should be done *before* XAA syncs,
+ * Otherwise will have to sync again???
+ */
+static void
+I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ int i, cmd, br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
+ drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+
+ /* Don't want to do this when no 3d is active and pages are
+ * right-way-round :
+ */
+ if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0)
+ return;
+
+ if (pScrn->bitsPerPixel == 32) {
+ cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+ XY_SRC_COPY_BLT_WRITE_RGB);
+ br13 |= 3 << 24;
+ } else {
+ cmd = (XY_SRC_COPY_BLT_CMD);
+ br13 |= 1 << 24;
+ }
+
+ for (i = 0 ; i < num ; i++, pbox++) {
+ BEGIN_LP_RING(8);
+ OUT_RING(cmd);
+ OUT_RING(br13);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING((pbox->y2 << 16) | pbox->x2);
+ OUT_RING(pI830->BackBuffer.Start);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING(br13 & 0xffff);
+ OUT_RING(pI830->FrontBuffer.Start);
+ ADVANCE_LP_RING();
+ }
+
+ DamageEmpty(pI830->pDamage);
+}
+#endif
+
static void
I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
DRIContextType oldContextType, void *oldContext,
@@ -1045,12 +1077,47 @@ I830DRISwapContext(ScreenPtr pScreen, DR
return;
pI830->LockHeld = 1;
I830RefreshRing(pScrn);
+
+#ifdef DAMAGE
+ if (!pI830->pDamage && pI830->allowPageFlip) {
+ PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
+ pI830->pDamage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+ pScreen, pPix);
+
+ if (pI830->pDamage == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No screen damage record, page flipping disabled\n");
+ pI830->allowPageFlip = 0;
+ } else {
+ DamageRegister(&pPix->drawable, pI830->pDamage);
+
+ DamageDamageRegion(&pPix->drawable,
+ &WindowTable[pScreen->myNum]->winSize);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Damage tracking initialized for page flipping\n");
+ }
+ }
+#endif
} else if (syncType == DRI_2D_SYNC &&
oldContextType == DRI_NO_CONTEXT &&
newContextType == DRI_2D_CONTEXT) {
pI830->LockHeld = 0;
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (out)\n");
+
+#ifdef DAMAGE
+ if (pI830->pDamage) {
+ RegionPtr pDamageReg = DamageRegion(pI830->pDamage);
+
+ if (pDamageReg) {
+ int nrects = REGION_NUM_RECTS(pDamageReg);
+
+ if (nrects)
+ I830DRIRefreshArea(pScrn, nrects, REGION_RECTS(pDamageReg));
+ }
+ }
+#endif
} else if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (other)\n");
}
@@ -1286,54 +1353,6 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
* might be faster, but seems like a lot more work...
*/
-
-#if 0
-/* This should be done *before* XAA syncs,
- * Otherwise will have to sync again???
- */
-static void
-I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- I830Ptr pI830 = I830PTR(pScrn);
- RegionPtr damage = &pBuf->damage;
- int i, num = REGION_NUM_RECTS(damage);
- BoxPtr pbox = REGION_RECTS(damage);
- drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
- int cmd, br13;
-
- /* Don't want to do this when no 3d is active and pages are
- * right-way-round :
- */
- if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0)
- return;
-
- br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
-
- if (pScrn->bitsPerPixel == 32) {
- cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
- br13 |= 3 << 24;
- } else {
- cmd = (XY_SRC_COPY_BLT_CMD);
- br13 |= 1 << 24;
- }
-
- for (i = 0 ; i < num ; i++, pbox++) {
- BEGIN_LP_RING(8);
- OUT_RING(cmd);
- OUT_RING(br13);
- OUT_RING((pbox->y1 << 16) | pbox->x1);
- OUT_RING((pbox->y2 << 16) | pbox->x2);
- OUT_RING(pI830->BackBuffer.Start);
- OUT_RING((pbox->y1 << 16) | pbox->x1);
- OUT_RING(br13 & 0xffff);
- OUT_RING(pI830->FrontBuffer.Start);
- ADVANCE_LP_RING();
- }
-}
-#endif
-
static void
I830EnablePageFlip(ScreenPtr pScreen)
{
@@ -1342,32 +1361,7 @@ I830EnablePageFlip(ScreenPtr pScreen)
drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
pSAREAPriv->pf_enabled = pI830->allowPageFlip;
- pSAREAPriv->pf_active = 0;
-
- if (pI830->allowPageFlip) {
- int br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
-
- BEGIN_LP_RING(8);
- if (pScrn->bitsPerPixel == 32) {
- OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
- br13 |= 3 << 24;
- } else {
- OUT_RING(XY_SRC_COPY_BLT_CMD);
- br13 |= 1 << 24;
- }
-
- OUT_RING(br13);
- OUT_RING(0);
- OUT_RING((pScrn->virtualY << 16) | pScrn->virtualX);
- OUT_RING(pI830->BackBuffer.Start);
- OUT_RING(0);
- OUT_RING(br13 & 0xffff);
- OUT_RING(pI830->FrontBuffer.Start);
- ADVANCE_LP_RING();
-
- pSAREAPriv->pf_active = 1;
- }
+ pSAREAPriv->pf_active = pI830->allowPageFlip;
}
static void
@@ -1419,14 +1413,13 @@ I830DRITransitionTo2d(ScreenPtr pScreen)
if (sPriv->pf_current_page == 1)
drmCommandNone(pI830->drmSubFD, DRM_I830_FLIP);
- /* Shut down shadowing if we've made it back to the front page:
- */
- if (sPriv->pf_current_page == 0) {
- I830DisablePageFlip(pScreen);
- }
+ if (sPriv->pf_current_page == 1)
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[dri] %s: kernel failed to unflip buffers.\n", __func__);
- pI830->have3DWindows = 0;
+ I830DisablePageFlip(pScreen);
+ pI830->have3DWindows = 0;
}
diff --git a/src/i830_driver.c b/src/i830_driver.c
index cb3dd87..d1f83e5 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3168,6 +3168,15 @@ I830CloseScreen(int scrnIndex, ScreenPtr
pI830->closing = TRUE;
#ifdef XF86DRI
if (pI830->directRenderingOpen) {
+#ifdef DAMAGE
+ if (pI830->pDamage) {
+ PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
+
+ DamageUnregister(&pPix->drawable, pI830->pDamage);
+ DamageDestroy(pI830->pDamage);
+ pI830->pDamage = NULL;
+ }
+#endif
#ifdef XF86DRI_MM
if (pI830->mmModeFlags & I830_KERNEL_MM) {
#ifndef XSERVER_LIBDRM_MM
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 6ceb05b..29d9d31 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -515,7 +515,7 @@ I830AllocateFramebuffer(ScrnInfoPtr pScr
int verbosity = dryrun ? 4 : 1;
const char *s = dryrun ? "[dryrun] " : "";
Bool tileable;
- int align, alignflags;
+ int align;
long size, alloced, fb_height;
/* Clear everything first. */
@@ -586,16 +586,6 @@ I830AllocateFramebuffer(ScrnInfoPtr pScr
tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
- if (tileable) {
- if (IS_I9XX(pI830))
- align = MB(1);
- else
- align = KB(512);
- alignflags = ALIGN_BOTH_ENDS;
- } else {
- align = KB(64);
- alignflags = 0;
- }
size = lineSize * (fb_height + cacheLines);
size = ROUND_TO_PAGE(size);
@@ -603,10 +593,26 @@ I830AllocateFramebuffer(ScrnInfoPtr pScr
"%sInitial %sframebuffer allocation size: %ld kByte\n",
s, secondary ? "secondary " : "",
size / 1024);
- alloced = I830AllocVidMem(pScrn, FrontBuffer,
- StolenPool, size, align,
- flags | alignflags |
- FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
+
+ if (tileable) {
+ align = GetBestTileAlignment(size);
+
+ for (align = GetBestTileAlignment(size);
+ align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
+ alloced = I830AllocVidMem(pScrn, FrontBuffer, StolenPool, size, align,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
+ ALIGN_BOTH_ENDS);
+ if (alloced >= size)
+ break;
+ }
+ } else {
+ align = KB(64);
+
+ alloced = I830AllocVidMem(pScrn, FrontBuffer,
+ StolenPool, size, align,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
+ }
+
if (alloced < size) {
if (!dryrun) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
@@ -718,7 +724,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn,
int verbosity = dryrun ? 4 : 1;
const char *s = dryrun ? "[dryrun] " : "";
Bool tileable;
- int align, alignflags, i;
+ int align, i;
DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n",
BOOLTOSTRING(flags & ALLOC_INITIAL));
@@ -877,20 +883,26 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn,
pI830->FbMemBox.y2 = maxFb / lineSize;
tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
+
if (tileable) {
- if (IS_I9XX(pI830))
- align = MB(1);
- else
- align = KB(512);
- alignflags = ALIGN_BOTH_ENDS;
+ align = GetBestTileAlignment(size);
+
+ for (align = GetBestTileAlignment(size);
+ align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
+ alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
+ &(pI830->StolenPool), size, align,
+ flags | FROM_ANYWHERE |
+ ALLOCATE_AT_TOP | ALIGN_BOTH_ENDS);
+ if (alloced >= size)
+ break;
+ }
} else {
- align = KB(64);
- alignflags = 0;
+ alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
+ &(pI830->StolenPool), maxFb, align,
+ flags |
+ FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
}
- alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
- &(pI830->StolenPool), maxFb, align,
- flags | alignflags |
- FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
+
if (alloced < maxFb) {
if (!dryrun) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
diff-tree 1d22bad33b634aaf61976907cb2ceeec8a9ebe4d (from 0df490938af10d3a748221e2fb5467b0f244f9eb)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Wed Feb 14 12:57:12 2007 +0100
Update SAREA pipe fields in i830PipeSetBase.
diff --git a/src/i830_display.c b/src/i830_display.c
index 345eea9..258897e 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -361,6 +361,31 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
(void) INREG(dspbase);
}
+
+#ifdef XF86DRI
+ if (pI830->directRenderingEnabled) {
+ drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen);
+
+ switch (pipe) {
+ case 0:
+ sPriv->pipeA_x = x;
+ sPriv->pipeA_y = y;
+ sPriv->pipeA_w = crtc->mode.HDisplay;
+ sPriv->pipeA_h = crtc->mode.VDisplay;
+ break;
+ case 1:
+ sPriv->pipeB_x = x;
+ sPriv->pipeB_y = y;
+ sPriv->pipeB_w = crtc->mode.HDisplay;
+ sPriv->pipeB_h = crtc->mode.VDisplay;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Can't update pipe %d in SAREA\n", pipe);
+ break;
+ }
+ }
+#endif
}
/**
diff-tree 0df490938af10d3a748221e2fb5467b0f244f9eb (from 1623b47c4863f5362587cdac855e3e11c109b007)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Dec 21 11:27:28 2006 +0100
If the DRM can handle it, enable vertical blank interrupts for both pipes.
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 70e7e49..3531bf5 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1497,7 +1497,10 @@ I830DRISetVBlankInterrupt (ScrnInfoPtr p
if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) {
if (on) {
if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled)
- pipe.pipe = DRM_I830_VBLANK_PIPE_B;
+ if (pI830->drmMinor >= 6)
+ pipe.pipe = DRM_I830_VBLANK_PIPE_A | DRM_I830_VBLANK_PIPE_B;
+ else
+ pipe.pipe = DRM_I830_VBLANK_PIPE_B;
else
pipe.pipe = DRM_I830_VBLANK_PIPE_A;
} else {
More information about the xorg-commit
mailing list