savage_dri.c revision ab47cfaa
1ab47cfaaSmrg/*
2ab47cfaaSmrg * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3ab47cfaaSmrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4ab47cfaaSmrg *
5ab47cfaaSmrg * Permission is hereby granted, free of charge, to any person obtaining a
6ab47cfaaSmrg * copy of this software and associated documentation files (the "Software"),
7ab47cfaaSmrg * to deal in the Software without restriction, including without limitation
8ab47cfaaSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
9ab47cfaaSmrg * and/or sell copies of the Software, and to permit persons to whom the
10ab47cfaaSmrg * Software is furnished to do so, subject to the following conditions:
11ab47cfaaSmrg *
12ab47cfaaSmrg * The above copyright notice and this permission notice (including the
13ab47cfaaSmrg * next paragraph) shall be included in all copies or substantial portions
14ab47cfaaSmrg * of the Software.
15ab47cfaaSmrg *
16ab47cfaaSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17ab47cfaaSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18ab47cfaaSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19ab47cfaaSmrg * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20ab47cfaaSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21ab47cfaaSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22ab47cfaaSmrg * DEALINGS IN THE SOFTWARE.
23ab47cfaaSmrg */
24ab47cfaaSmrg
25ab47cfaaSmrg#ifdef HAVE_CONFIG_H
26ab47cfaaSmrg#include "config.h"
27ab47cfaaSmrg#endif
28ab47cfaaSmrg
29ab47cfaaSmrg#ifdef XF86DRI
30ab47cfaaSmrg
31ab47cfaaSmrg#include "xf86.h"
32ab47cfaaSmrg#include "xf86_OSproc.h"
33ab47cfaaSmrg#include "xf86Priv.h"
34ab47cfaaSmrg
35ab47cfaaSmrg#include "xaalocal.h"
36ab47cfaaSmrg#include "xaarop.h"
37ab47cfaaSmrg
38ab47cfaaSmrg#include "xf86PciInfo.h"
39ab47cfaaSmrg#include "xf86Pci.h"
40ab47cfaaSmrg#include "xf86fbman.h"
41ab47cfaaSmrg
42ab47cfaaSmrg#include "miline.h"
43ab47cfaaSmrg
44ab47cfaaSmrg
45ab47cfaaSmrg/*#include "savage_vbe.h"*/
46ab47cfaaSmrg#include "savage_regs.h"
47ab47cfaaSmrg#include "savage_driver.h"
48ab47cfaaSmrg#include "savage_bci.h"
49ab47cfaaSmrg#include "savage_streams.h"
50ab47cfaaSmrg#include "savage_common.h"
51ab47cfaaSmrg
52ab47cfaaSmrg#define _XF86DRI_SERVER_
53ab47cfaaSmrg#include "GL/glxtokens.h"
54ab47cfaaSmrg#include "sarea.h"
55ab47cfaaSmrg#include "savage_dri.h"
56ab47cfaaSmrg#include "savage_sarea.h"
57ab47cfaaSmrg
58ab47cfaaSmrgstatic char SAVAGEKernelDriverName[] = "savage";
59ab47cfaaSmrgstatic char SAVAGEClientDriverName[] = "savage";
60ab47cfaaSmrg
61ab47cfaaSmrgstatic Bool SAVAGEDRIOpenFullScreen(ScreenPtr pScreen);
62ab47cfaaSmrgstatic Bool SAVAGEDRICloseFullScreen(ScreenPtr pScreen);
63ab47cfaaSmrg/* DRI buffer management
64ab47cfaaSmrg */
65ab47cfaaSmrgvoid SAVAGEDRIInitBuffers( WindowPtr pWin, RegionPtr prgn,
66ab47cfaaSmrg				CARD32 index );
67ab47cfaaSmrgvoid SAVAGEDRIMoveBuffers( WindowPtr pParent, DDXPointRec ptOldOrg,
68ab47cfaaSmrg				RegionPtr prgnSrc, CARD32 index );
69ab47cfaaSmrg
70ab47cfaaSmrg/*        almost the same besides set src/desc to */
71ab47cfaaSmrg/*        Primary Bitmap Description              */
72ab47cfaaSmrg
73ab47cfaaSmrgstatic void
74ab47cfaaSmrgSAVAGEDRISetupForScreenToScreenCopy(
75ab47cfaaSmrg    ScrnInfoPtr pScrn, int xdir, int ydir,
76ab47cfaaSmrg    int rop, unsigned planemask, int transparency_color);
77ab47cfaaSmrg
78ab47cfaaSmrg
79ab47cfaaSmrgstatic void
80ab47cfaaSmrgSAVAGEDRISubsequentScreenToScreenCopy(
81ab47cfaaSmrg    ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
82ab47cfaaSmrg    int w, int h);
83ab47cfaaSmrg
84ab47cfaaSmrg
85ab47cfaaSmrg/* Initialize the visual configs that are supported by the hardware.
86ab47cfaaSmrg * These are combined with the visual configs that the indirect
87ab47cfaaSmrg * rendering core supports, and the intersection is exported to the
88ab47cfaaSmrg * client.
89ab47cfaaSmrg */
90ab47cfaaSmrgstatic Bool SAVAGEInitVisualConfigs( ScreenPtr pScreen )
91ab47cfaaSmrg{
92ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
93ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
94ab47cfaaSmrg   int numConfigs = 0;
95ab47cfaaSmrg   __GLXvisualConfig *pConfigs = 0;
96ab47cfaaSmrg   SAVAGEConfigPrivPtr pSAVAGEConfigs = 0;
97ab47cfaaSmrg   SAVAGEConfigPrivPtr *pSAVAGEConfigPtrs = 0;
98ab47cfaaSmrg   int i, db, depth, stencil, accum;
99ab47cfaaSmrg
100ab47cfaaSmrg   switch ( pScrn->bitsPerPixel ) {
101ab47cfaaSmrg   case 8:
102ab47cfaaSmrg   case 24:
103ab47cfaaSmrg      break;
104ab47cfaaSmrg
105ab47cfaaSmrg   case 16:
106ab47cfaaSmrg      numConfigs = 8;
107ab47cfaaSmrg
108ab47cfaaSmrg      pConfigs = (__GLXvisualConfig*)xcalloc( sizeof(__GLXvisualConfig),
109ab47cfaaSmrg						numConfigs );
110ab47cfaaSmrg      if ( !pConfigs ) {
111ab47cfaaSmrg	 return FALSE;
112ab47cfaaSmrg      }
113ab47cfaaSmrg
114ab47cfaaSmrg      pSAVAGEConfigs = (SAVAGEConfigPrivPtr)xcalloc( sizeof(SAVAGEConfigPrivRec),
115ab47cfaaSmrg						 numConfigs );
116ab47cfaaSmrg      if ( !pSAVAGEConfigs ) {
117ab47cfaaSmrg	 xfree( pConfigs );
118ab47cfaaSmrg	 return FALSE;
119ab47cfaaSmrg      }
120ab47cfaaSmrg
121ab47cfaaSmrg      pSAVAGEConfigPtrs = (SAVAGEConfigPrivPtr*)xcalloc( sizeof(SAVAGEConfigPrivPtr),
122ab47cfaaSmrg						     numConfigs );
123ab47cfaaSmrg      if ( !pSAVAGEConfigPtrs ) {
124ab47cfaaSmrg	 xfree( pConfigs );
125ab47cfaaSmrg	 xfree( pSAVAGEConfigs );
126ab47cfaaSmrg	 return FALSE;
127ab47cfaaSmrg      }
128ab47cfaaSmrg
129ab47cfaaSmrg      for ( i = 0 ; i < numConfigs ; i++ ) {
130ab47cfaaSmrg	 pSAVAGEConfigPtrs[i] = &pSAVAGEConfigs[i];
131ab47cfaaSmrg      }
132ab47cfaaSmrg
133ab47cfaaSmrg      i = 0;
134ab47cfaaSmrg      depth = 1;
135ab47cfaaSmrg      for ( accum = 0 ; accum <= 1 ; accum++ ) {
136ab47cfaaSmrg         for ( stencil = 0 ; stencil <= 1 ; stencil++ ) {
137ab47cfaaSmrg            for ( db = 1 ; db >= 0 ; db-- ) {
138ab47cfaaSmrg               pConfigs[i].vid			= -1;
139ab47cfaaSmrg               pConfigs[i].class		= -1;
140ab47cfaaSmrg               pConfigs[i].rgba			= TRUE;
141ab47cfaaSmrg               pConfigs[i].redSize		= 5;
142ab47cfaaSmrg               pConfigs[i].greenSize		= 6;
143ab47cfaaSmrg               pConfigs[i].blueSize		= 5;
144ab47cfaaSmrg               pConfigs[i].alphaSize		= 0;
145ab47cfaaSmrg               pConfigs[i].redMask		= 0x0000F800;
146ab47cfaaSmrg               pConfigs[i].greenMask		= 0x000007E0;
147ab47cfaaSmrg               pConfigs[i].blueMask		= 0x0000001F;
148ab47cfaaSmrg               pConfigs[i].alphaMask		= 0;
149ab47cfaaSmrg               if ( accum ) {
150ab47cfaaSmrg                  pConfigs[i].accumRedSize	= 16;
151ab47cfaaSmrg                  pConfigs[i].accumGreenSize	= 16;
152ab47cfaaSmrg                  pConfigs[i].accumBlueSize	= 16;
153ab47cfaaSmrg                  pConfigs[i].accumAlphaSize	= 0;
154ab47cfaaSmrg               } else {
155ab47cfaaSmrg                  pConfigs[i].accumRedSize	= 0;
156ab47cfaaSmrg                  pConfigs[i].accumGreenSize	= 0;
157ab47cfaaSmrg                  pConfigs[i].accumBlueSize	= 0;
158ab47cfaaSmrg                  pConfigs[i].accumAlphaSize	= 0;
159ab47cfaaSmrg               }
160ab47cfaaSmrg               if ( db ) {
161ab47cfaaSmrg                  pConfigs[i].doubleBuffer	= TRUE;
162ab47cfaaSmrg               } else {
163ab47cfaaSmrg                  pConfigs[i].doubleBuffer	= FALSE;
164ab47cfaaSmrg	       }
165ab47cfaaSmrg               pConfigs[i].stereo		= FALSE;
166ab47cfaaSmrg               pConfigs[i].bufferSize		= 16;
167ab47cfaaSmrg               if ( depth ) {
168ab47cfaaSmrg                  pConfigs[i].depthSize		= 16;
169ab47cfaaSmrg               } else {
170ab47cfaaSmrg                  pConfigs[i].depthSize		= 0;
171ab47cfaaSmrg	       }
172ab47cfaaSmrg               if ( stencil ) {
173ab47cfaaSmrg                  pConfigs[i].stencilSize	= 8;
174ab47cfaaSmrg               } else {
175ab47cfaaSmrg                  pConfigs[i].stencilSize	= 0;
176ab47cfaaSmrg	       }
177ab47cfaaSmrg               pConfigs[i].auxBuffers		= 0;
178ab47cfaaSmrg               pConfigs[i].level		= 0;
179ab47cfaaSmrg               if ( accum || stencil ) {
180ab47cfaaSmrg		  pConfigs[i].visualRating	= GLX_SLOW_CONFIG;
181ab47cfaaSmrg               } else {
182ab47cfaaSmrg                  pConfigs[i].visualRating	= GLX_NONE;
183ab47cfaaSmrg	       }
184ab47cfaaSmrg               pConfigs[i].transparentPixel	= GLX_NONE;
185ab47cfaaSmrg               pConfigs[i].transparentRed	= 0;
186ab47cfaaSmrg               pConfigs[i].transparentGreen	= 0;
187ab47cfaaSmrg               pConfigs[i].transparentBlue	= 0;
188ab47cfaaSmrg               pConfigs[i].transparentAlpha	= 0;
189ab47cfaaSmrg               pConfigs[i].transparentIndex	= 0;
190ab47cfaaSmrg               i++;
191ab47cfaaSmrg            }
192ab47cfaaSmrg         }
193ab47cfaaSmrg      }
194ab47cfaaSmrg      if ( i != numConfigs ) {
195ab47cfaaSmrg         xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
196ab47cfaaSmrg		     "[drm] Incorrect initialization of visuals\n" );
197ab47cfaaSmrg         return FALSE;
198ab47cfaaSmrg      }
199ab47cfaaSmrg      break;
200ab47cfaaSmrg
201ab47cfaaSmrg   case 32:
202ab47cfaaSmrg      numConfigs = 8;
203ab47cfaaSmrg
204ab47cfaaSmrg      pConfigs = (__GLXvisualConfig*)xcalloc( sizeof(__GLXvisualConfig),
205ab47cfaaSmrg						numConfigs );
206ab47cfaaSmrg      if ( !pConfigs ) {
207ab47cfaaSmrg	 return FALSE;
208ab47cfaaSmrg      }
209ab47cfaaSmrg
210ab47cfaaSmrg      pSAVAGEConfigs = (SAVAGEConfigPrivPtr)xcalloc( sizeof(SAVAGEConfigPrivRec),
211ab47cfaaSmrg						 numConfigs );
212ab47cfaaSmrg      if ( !pSAVAGEConfigs ) {
213ab47cfaaSmrg	 xfree( pConfigs );
214ab47cfaaSmrg	 return FALSE;
215ab47cfaaSmrg      }
216ab47cfaaSmrg
217ab47cfaaSmrg      pSAVAGEConfigPtrs = (SAVAGEConfigPrivPtr*)xcalloc( sizeof(SAVAGEConfigPrivPtr),
218ab47cfaaSmrg						     numConfigs );
219ab47cfaaSmrg      if ( !pSAVAGEConfigPtrs ) {
220ab47cfaaSmrg	 xfree( pConfigs );
221ab47cfaaSmrg	 xfree( pSAVAGEConfigs );
222ab47cfaaSmrg	 return FALSE;
223ab47cfaaSmrg      }
224ab47cfaaSmrg
225ab47cfaaSmrg      for ( i = 0 ; i < numConfigs ; i++ ) {
226ab47cfaaSmrg	 pSAVAGEConfigPtrs[i] = &pSAVAGEConfigs[i];
227ab47cfaaSmrg      }
228ab47cfaaSmrg
229ab47cfaaSmrg      i = 0;
230ab47cfaaSmrg      for ( accum = 0 ; accum <= 1 ; accum++ ) {
231ab47cfaaSmrg         for ( stencil = 0 ; stencil <= 1 ; stencil++ ) {
232ab47cfaaSmrg            for ( db = 1 ; db >= 0 ; db-- ) {
233ab47cfaaSmrg               pConfigs[i].vid			= -1;
234ab47cfaaSmrg               pConfigs[i].class		= -1;
235ab47cfaaSmrg               pConfigs[i].rgba			= TRUE;
236ab47cfaaSmrg               pConfigs[i].redSize		= 8;
237ab47cfaaSmrg               pConfigs[i].greenSize		= 8;
238ab47cfaaSmrg               pConfigs[i].blueSize		= 8;
239ab47cfaaSmrg               pConfigs[i].alphaSize		= 0;
240ab47cfaaSmrg               pConfigs[i].redMask		= 0x00FF0000;
241ab47cfaaSmrg               pConfigs[i].greenMask		= 0x0000FF00;
242ab47cfaaSmrg               pConfigs[i].blueMask		= 0x000000FF;
243ab47cfaaSmrg               pConfigs[i].alphaMask		= 0;
244ab47cfaaSmrg               if ( accum ) {
245ab47cfaaSmrg                  pConfigs[i].accumRedSize	= 16;
246ab47cfaaSmrg                  pConfigs[i].accumGreenSize	= 16;
247ab47cfaaSmrg                  pConfigs[i].accumBlueSize	= 16;
248ab47cfaaSmrg                  pConfigs[i].accumAlphaSize	= 0;
249ab47cfaaSmrg               } else {
250ab47cfaaSmrg                  pConfigs[i].accumRedSize	= 0;
251ab47cfaaSmrg                  pConfigs[i].accumGreenSize	= 0;
252ab47cfaaSmrg                  pConfigs[i].accumBlueSize	= 0;
253ab47cfaaSmrg                  pConfigs[i].accumAlphaSize	= 0;
254ab47cfaaSmrg               }
255ab47cfaaSmrg               if ( db ) {
256ab47cfaaSmrg                  pConfigs[i].doubleBuffer	= TRUE;
257ab47cfaaSmrg               } else {
258ab47cfaaSmrg                  pConfigs[i].doubleBuffer	= FALSE;
259ab47cfaaSmrg	       }
260ab47cfaaSmrg               pConfigs[i].stereo		= FALSE;
261ab47cfaaSmrg               pConfigs[i].bufferSize		= 32;
262ab47cfaaSmrg               if ( stencil ) {
263ab47cfaaSmrg		     pConfigs[i].depthSize	= 24;
264ab47cfaaSmrg                     pConfigs[i].stencilSize	= 8;
265ab47cfaaSmrg               }
266ab47cfaaSmrg               else {
267ab47cfaaSmrg                     pConfigs[i].depthSize	= 24;
268ab47cfaaSmrg                     pConfigs[i].stencilSize	= 0;
269ab47cfaaSmrg               }
270ab47cfaaSmrg               pConfigs[i].auxBuffers		= 0;
271ab47cfaaSmrg               pConfigs[i].level		= 0;
272ab47cfaaSmrg               if ( accum ) {
273ab47cfaaSmrg                  pConfigs[i].visualRating	= GLX_SLOW_VISUAL_EXT;
274ab47cfaaSmrg               } else {
275ab47cfaaSmrg                  pConfigs[i].visualRating	= GLX_NONE;
276ab47cfaaSmrg	       }
277ab47cfaaSmrg               pConfigs[i].transparentPixel	= GLX_NONE;
278ab47cfaaSmrg               pConfigs[i].transparentRed	= 0;
279ab47cfaaSmrg               pConfigs[i].transparentGreen	= 0;
280ab47cfaaSmrg               pConfigs[i].transparentBlue	= 0;
281ab47cfaaSmrg               pConfigs[i].transparentAlpha	= 0;
282ab47cfaaSmrg               pConfigs[i].transparentIndex	= 0;
283ab47cfaaSmrg               i++;
284ab47cfaaSmrg            }
285ab47cfaaSmrg         }
286ab47cfaaSmrg      }
287ab47cfaaSmrg      if ( i != numConfigs ) {
288ab47cfaaSmrg         xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
289ab47cfaaSmrg		     "[drm] Incorrect initialization of visuals\n" );
290ab47cfaaSmrg         return FALSE;
291ab47cfaaSmrg      }
292ab47cfaaSmrg      break;
293ab47cfaaSmrg
294ab47cfaaSmrg   default:
295ab47cfaaSmrg      /* Unexpected bits/pixels */
296ab47cfaaSmrg      break;
297ab47cfaaSmrg   }
298ab47cfaaSmrg
299ab47cfaaSmrg   psav->numVisualConfigs = numConfigs;
300ab47cfaaSmrg   psav->pVisualConfigs = pConfigs;
301ab47cfaaSmrg   psav->pVisualConfigsPriv = pSAVAGEConfigs;
302ab47cfaaSmrg
303ab47cfaaSmrg   GlxSetVisualConfigs( numConfigs, pConfigs, (void **)pSAVAGEConfigPtrs );
304ab47cfaaSmrg
305ab47cfaaSmrg   return TRUE;
306ab47cfaaSmrg}
307ab47cfaaSmrg
308ab47cfaaSmrgstatic Bool SAVAGECreateContext( ScreenPtr pScreen, VisualPtr visual,
309ab47cfaaSmrg			      drm_context_t hwContext, void *pVisualConfigPriv,
310ab47cfaaSmrg			      DRIContextType contextStore )
311ab47cfaaSmrg{
312ab47cfaaSmrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
313ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
314ab47cfaaSmrg
315ab47cfaaSmrg    if(psav->xvmcContext)
316ab47cfaaSmrg        return FALSE;
317ab47cfaaSmrg    else
318ab47cfaaSmrg    {
319ab47cfaaSmrg        psav->DRIrunning++;
320ab47cfaaSmrg    }
321ab47cfaaSmrg
322ab47cfaaSmrg    return TRUE;
323ab47cfaaSmrg}
324ab47cfaaSmrg
325ab47cfaaSmrgstatic void SAVAGEDestroyContext( ScreenPtr pScreen, drm_context_t hwContext,
326ab47cfaaSmrg			       DRIContextType contextStore )
327ab47cfaaSmrg{
328ab47cfaaSmrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
329ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
330ab47cfaaSmrg
331ab47cfaaSmrg    psav->DRIrunning--;
332ab47cfaaSmrg}
333ab47cfaaSmrg
334ab47cfaaSmrgstatic void SAVAGEWakeupHandler( int screenNum, pointer wakeupData,
335ab47cfaaSmrg				 unsigned long result, pointer pReadmask )
336ab47cfaaSmrg{
337ab47cfaaSmrg   ScreenPtr pScreen = screenInfo.screens[screenNum];
338ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
339ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
340ab47cfaaSmrg
341ab47cfaaSmrg   psav->pDRIInfo->wrap.WakeupHandler = psav->coreWakeupHandler;
342ab47cfaaSmrg   (*psav->pDRIInfo->wrap.WakeupHandler) (screenNum, wakeupData, result, pReadmask);
343ab47cfaaSmrg   psav->pDRIInfo->wrap.WakeupHandler = SAVAGEWakeupHandler;
344ab47cfaaSmrg   psav->LockHeld = 1;
345ab47cfaaSmrg   if (psav->ShadowStatus) {
346ab47cfaaSmrg      /* fetch the global shadow counter */
347ab47cfaaSmrg#if 0
348ab47cfaaSmrg      if (psav->ShadowCounter != (psav->ShadowVirtual[1023] & 0xffff))
349ab47cfaaSmrg	 xf86DrvMsg( pScrn->scrnIndex, X_INFO,
350ab47cfaaSmrg		     "[dri] WakeupHandler: shadowCounter adjusted from %04x to %04lx\n",
351ab47cfaaSmrg		     psav->ShadowCounter, psav->ShadowVirtual[1023] & 0xffff);
352ab47cfaaSmrg#endif
353ab47cfaaSmrg      psav->ShadowCounter = psav->ShadowVirtual[1023] & 0xffff;
354ab47cfaaSmrg   }
355ab47cfaaSmrg   if (psav->useEXA)
356ab47cfaaSmrg	exaMarkSync(pScreen);
357ab47cfaaSmrg   else
358ab47cfaaSmrg	psav->AccelInfoRec->NeedToSync = TRUE;
359ab47cfaaSmrg   /* FK: this flag doesn't seem to be used. */
360ab47cfaaSmrg}
361ab47cfaaSmrg
362ab47cfaaSmrgstatic void SAVAGEBlockHandler( int screenNum, pointer blockData,
363ab47cfaaSmrg				pointer pTimeout, pointer pReadmask)
364ab47cfaaSmrg{
365ab47cfaaSmrg   ScreenPtr pScreen = screenInfo.screens[screenNum];
366ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
367ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
368ab47cfaaSmrg
369ab47cfaaSmrg   if (psav->ShadowStatus) {
370ab47cfaaSmrg      /* update the global shadow counter */
371ab47cfaaSmrg      CARD32 globalShadowCounter = psav->ShadowVirtual[1023];
372ab47cfaaSmrg      globalShadowCounter = (globalShadowCounter & 0xffff0000) |
373ab47cfaaSmrg	  ((CARD32)psav->ShadowCounter & 0x0000ffff);
374ab47cfaaSmrg
375ab47cfaaSmrg#if 0
376ab47cfaaSmrg      if (globalShadowCounter != psav->ShadowVirtual[1023])
377ab47cfaaSmrg	 xf86DrvMsg( pScrn->scrnIndex, X_INFO,
378ab47cfaaSmrg		     "[dri] BlockHandler: shadowCounter adjusted from %08lx to %08x\n",
379ab47cfaaSmrg		     psav->ShadowVirtual[1023], globalShadowCounter);
380ab47cfaaSmrg#endif
381ab47cfaaSmrg      psav->ShadowVirtual[1023] = globalShadowCounter;
382ab47cfaaSmrg   }
383ab47cfaaSmrg   psav->LockHeld = 0;
384ab47cfaaSmrg   psav->pDRIInfo->wrap.BlockHandler = psav->coreBlockHandler;
385ab47cfaaSmrg   (*psav->pDRIInfo->wrap.BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
386ab47cfaaSmrg   psav->pDRIInfo->wrap.BlockHandler = SAVAGEBlockHandler;
387ab47cfaaSmrg}
388ab47cfaaSmrg
389ab47cfaaSmrgvoid SAVAGESelectBuffer( ScrnInfoPtr pScrn, int which )
390ab47cfaaSmrg{
391ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
392ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
393ab47cfaaSmrg
394ab47cfaaSmrg   psav->WaitIdleEmpty(psav);
395ab47cfaaSmrg
396ab47cfaaSmrg   OUTREG(0x48C18,INREG(0x48C18)&(~0x00000008));
397ab47cfaaSmrg
398ab47cfaaSmrg   switch ( which ) {
399ab47cfaaSmrg   case SAVAGE_BACK:
400ab47cfaaSmrg      OUTREG( 0x8170, pSAVAGEDRIServer->backOffset );
401ab47cfaaSmrg      OUTREG( 0x8174, pSAVAGEDRIServer->backBitmapDesc );
402ab47cfaaSmrg      break;
403ab47cfaaSmrg   case SAVAGE_DEPTH:
404ab47cfaaSmrg      OUTREG( 0x8170, pSAVAGEDRIServer->depthOffset );
405ab47cfaaSmrg      OUTREG( 0x8174, pSAVAGEDRIServer->depthBitmapDesc );
406ab47cfaaSmrg      break;
407ab47cfaaSmrg   default:
408ab47cfaaSmrg   case SAVAGE_FRONT:
409ab47cfaaSmrg      OUTREG( 0x8170, pSAVAGEDRIServer->frontOffset );
410ab47cfaaSmrg      OUTREG( 0x8174, pSAVAGEDRIServer->frontBitmapDesc );
411ab47cfaaSmrg      break;
412ab47cfaaSmrg   }
413ab47cfaaSmrg   OUTREG(0x48C18,INREG(0x48C18)|(0x00000008));
414ab47cfaaSmrg   psav->WaitIdleEmpty(psav);
415ab47cfaaSmrg
416ab47cfaaSmrg}
417ab47cfaaSmrg
418ab47cfaaSmrg
419ab47cfaaSmrgstatic unsigned int mylog2( unsigned int n )
420ab47cfaaSmrg{
421ab47cfaaSmrg   unsigned int log2 = 1;
422ab47cfaaSmrg
423ab47cfaaSmrg   n--;
424ab47cfaaSmrg   while ( n > 1 ) n >>= 1, log2++;
425ab47cfaaSmrg
426ab47cfaaSmrg   return log2;
427ab47cfaaSmrg}
428ab47cfaaSmrg
429ab47cfaaSmrgstatic Bool SAVAGEDRIAgpInit(ScreenPtr pScreen)
430ab47cfaaSmrg{
431ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
432ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
433ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
434ab47cfaaSmrg   unsigned long mode;
435ab47cfaaSmrg   unsigned int vendor, device;
436ab47cfaaSmrg   unsigned int offset;
437ab47cfaaSmrg   int ret;
438ab47cfaaSmrg
439ab47cfaaSmrg   if (psav->agpSize < 2) psav->agpSize = 2; /* at least 2MB for DMA buffers */
440ab47cfaaSmrg
441ab47cfaaSmrg   pSAVAGEDRIServer->agp.size = psav->agpSize * 1024 * 1024;
442ab47cfaaSmrg   pSAVAGEDRIServer->agp.offset = pSAVAGEDRIServer->agp.size; /* ? */
443ab47cfaaSmrg
444ab47cfaaSmrg   if ( drmAgpAcquire( psav->drmFD ) < 0 ) {
445ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not available\n" );
446ab47cfaaSmrg      return FALSE;
447ab47cfaaSmrg   }
448ab47cfaaSmrg
449ab47cfaaSmrg   mode   = drmAgpGetMode( psav->drmFD );        /* Default mode */
450ab47cfaaSmrg   vendor = drmAgpVendorId( psav->drmFD );
451ab47cfaaSmrg   device = drmAgpDeviceId( psav->drmFD );
452ab47cfaaSmrg
453ab47cfaaSmrg   mode &= ~SAVAGE_AGP_MODE_MASK;
454ab47cfaaSmrg
455ab47cfaaSmrg   switch ( psav->agpMode ) {
456ab47cfaaSmrg   case 4:
457ab47cfaaSmrg      mode |= SAVAGE_AGP_4X_MODE;
458ab47cfaaSmrg   case 2:
459ab47cfaaSmrg      mode |= SAVAGE_AGP_2X_MODE;
460ab47cfaaSmrg   case 1:
461ab47cfaaSmrg   default:
462ab47cfaaSmrg      mode |= SAVAGE_AGP_1X_MODE;
463ab47cfaaSmrg   }
464ab47cfaaSmrg
465ab47cfaaSmrg   /*   mode |= SAVAGE_AGP_1X_MODE;*/
466ab47cfaaSmrg
467ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
468ab47cfaaSmrg	       "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
469ab47cfaaSmrg	       mode, vendor, device,
470ab47cfaaSmrg	       psav->PciInfo->vendor,
471ab47cfaaSmrg	       psav->PciInfo->chipType );
472ab47cfaaSmrg
473ab47cfaaSmrg   if ( drmAgpEnable( psav->drmFD, mode ) < 0 ) {
474ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" );
475ab47cfaaSmrg      drmAgpRelease( psav->drmFD );
476ab47cfaaSmrg      pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */
477ab47cfaaSmrg      return FALSE;
478ab47cfaaSmrg   }
479ab47cfaaSmrg
480ab47cfaaSmrg   ret = drmAgpAlloc( psav->drmFD, pSAVAGEDRIServer->agp.size,
481ab47cfaaSmrg		      0, NULL, &pSAVAGEDRIServer->agp.handle );
482ab47cfaaSmrg   if ( ret < 0 ) {
483ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret );
484ab47cfaaSmrg      drmAgpRelease( psav->drmFD );
485ab47cfaaSmrg      pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */
486ab47cfaaSmrg      return FALSE;
487ab47cfaaSmrg   }
488ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
489ab47cfaaSmrg	       "[agp] %d kB allocated with handle 0x%08lx\n",
490ab47cfaaSmrg	       pSAVAGEDRIServer->agp.size/1024, pSAVAGEDRIServer->agp.handle );
491ab47cfaaSmrg
492ab47cfaaSmrg   if ( drmAgpBind( psav->drmFD, pSAVAGEDRIServer->agp.handle, 0 ) < 0 ) {
493ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind memory\n" );
494ab47cfaaSmrg      drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle );
495ab47cfaaSmrg      drmAgpRelease( psav->drmFD );
496ab47cfaaSmrg      pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */
497ab47cfaaSmrg      return FALSE;
498ab47cfaaSmrg   }
499ab47cfaaSmrg
500ab47cfaaSmrg   /* AGP initialization failures above are not fatal, we can fall
501ab47cfaaSmrg    * back to PCI mode. Failures while adding AGP mappings below are
502ab47cfaaSmrg    * fatal though. DRI must be disabled in that case.
503ab47cfaaSmrg    * pSAVAGEDRIServer->agp.handle can be used to distinguish these
504ab47cfaaSmrg    * two cases.
505ab47cfaaSmrg    */
506ab47cfaaSmrg
507ab47cfaaSmrg   /* AGP memory layout
508ab47cfaaSmrg    */
509ab47cfaaSmrg   offset = 0;
510ab47cfaaSmrg
511ab47cfaaSmrg   if ( psav->AgpDMA ) {
512ab47cfaaSmrg       if ( psav->CommandDMA ) {
513ab47cfaaSmrg	   pSAVAGEDRIServer->cmdDma.offset = offset;
514ab47cfaaSmrg	   pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE;
515ab47cfaaSmrg	   offset += pSAVAGEDRIServer->cmdDma.size;
516ab47cfaaSmrg       } else if ( psav->VertexDMA ) {
517ab47cfaaSmrg	   pSAVAGEDRIServer->buffers.offset = 0;
518ab47cfaaSmrg	   pSAVAGEDRIServer->buffers.size = SAVAGE_NUM_BUFFERS * SAVAGE_BUFFER_SIZE;
519ab47cfaaSmrg	   offset += pSAVAGEDRIServer->buffers.size;
520ab47cfaaSmrg       }
521ab47cfaaSmrg   }
522ab47cfaaSmrg
523ab47cfaaSmrg   pSAVAGEDRIServer->agpTextures.offset = offset;
524ab47cfaaSmrg   pSAVAGEDRIServer->agpTextures.size = (pSAVAGEDRIServer->agp.size - offset);
525ab47cfaaSmrg
526ab47cfaaSmrg   /* DMA buffers
527ab47cfaaSmrg    */
528ab47cfaaSmrg   if ( psav->AgpDMA ) {
529ab47cfaaSmrg       if ( psav->CommandDMA ) {
530ab47cfaaSmrg	   if ( drmAddMap( psav->drmFD,
531ab47cfaaSmrg			   pSAVAGEDRIServer->cmdDma.offset,
532ab47cfaaSmrg			   pSAVAGEDRIServer->cmdDma.size,
533ab47cfaaSmrg			   DRM_AGP, DRM_RESTRICTED | DRM_KERNEL,
534ab47cfaaSmrg			   &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) {
535ab47cfaaSmrg	       xf86DrvMsg( pScreen->myNum, X_ERROR,
536ab47cfaaSmrg			   "[agp] Could not add command DMA mapping\n" );
537ab47cfaaSmrg	       return FALSE;
538ab47cfaaSmrg	   }
539ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
540ab47cfaaSmrg		       "[agp] command DMA handle = 0x%08lx\n",
541ab47cfaaSmrg		       pSAVAGEDRIServer->cmdDma.handle );
542ab47cfaaSmrg	   /* not needed in the server
543ab47cfaaSmrg	   if ( drmMap( psav->drmFD,
544ab47cfaaSmrg			pSAVAGEDRIServer->cmdDma.handle,
545ab47cfaaSmrg			pSAVAGEDRIServer->cmdDma.size,
546ab47cfaaSmrg			&pSAVAGEDRIServer->cmdDma.map ) < 0 ) {
547ab47cfaaSmrg	       xf86DrvMsg( pScreen->myNum, X_ERROR,
548ab47cfaaSmrg			   "[agp] Could not map command DMA\n" );
549ab47cfaaSmrg	       return FALSE;
550ab47cfaaSmrg	   }
551ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
552ab47cfaaSmrg		       "[agp] command DMA mapped at 0x%08lx\n",
553ab47cfaaSmrg		       (unsigned long)pSAVAGEDRIServer->cmdDma.map );
554ab47cfaaSmrg	   */
555ab47cfaaSmrg       } else if ( psav->VertexDMA ) {
556ab47cfaaSmrg	   if ( drmAddMap( psav->drmFD,
557ab47cfaaSmrg			   pSAVAGEDRIServer->buffers.offset,
558ab47cfaaSmrg			   pSAVAGEDRIServer->buffers.size,
559ab47cfaaSmrg			   DRM_AGP, 0,
560ab47cfaaSmrg			   &pSAVAGEDRIServer->buffers.handle ) < 0 ) {
561ab47cfaaSmrg	       xf86DrvMsg( pScreen->myNum, X_ERROR,
562ab47cfaaSmrg			   "[agp] Could not add DMA buffers mapping\n" );
563ab47cfaaSmrg	       return FALSE;
564ab47cfaaSmrg	   }
565ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
566ab47cfaaSmrg		       "[agp] DMA buffers handle = 0x%08lx\n",
567ab47cfaaSmrg		       pSAVAGEDRIServer->buffers.handle );
568ab47cfaaSmrg	   /* not needed in the server
569ab47cfaaSmrg	   if ( drmMap( psav->drmFD,
570ab47cfaaSmrg			pSAVAGEDRIServer->buffers.handle,
571ab47cfaaSmrg			pSAVAGEDRIServer->buffers.size,
572ab47cfaaSmrg			&pSAVAGEDRIServer->buffers.map ) < 0 ) {
573ab47cfaaSmrg	       xf86DrvMsg( pScreen->myNum, X_ERROR,
574ab47cfaaSmrg			   "[agp] Could not map DMA buffers\n" );
575ab47cfaaSmrg	       return FALSE;
576ab47cfaaSmrg	   }
577ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
578ab47cfaaSmrg		       "[agp] DMA buffers mapped at 0x%08lx\n",
579ab47cfaaSmrg		       (unsigned long)pSAVAGEDRIServer->buffers.map );
580ab47cfaaSmrg	   */
581ab47cfaaSmrg       }
582ab47cfaaSmrg   }
583ab47cfaaSmrg
584ab47cfaaSmrg   /* AGP textures
585ab47cfaaSmrg    */
586ab47cfaaSmrg   if ( drmAddMap( psav->drmFD,
587ab47cfaaSmrg		   pSAVAGEDRIServer->agpTextures.offset,
588ab47cfaaSmrg		   pSAVAGEDRIServer->agpTextures.size,
589ab47cfaaSmrg		   DRM_AGP, 0,
590ab47cfaaSmrg		   &pSAVAGEDRIServer->agpTextures.handle ) < 0 ) {
591ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
592ab47cfaaSmrg		  "[agp] Could not add agpTextures \n" );
593ab47cfaaSmrg      return FALSE;
594ab47cfaaSmrg   }
595ab47cfaaSmrg   /*   pSAVAGEDRIServer->agp_offset=pSAVAGEDRIServer->agpTexture.size;*/
596ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
597ab47cfaaSmrg	       "[agp] agpTextures handle = 0x%08lx\n",
598ab47cfaaSmrg	       pSAVAGEDRIServer->agpTextures.handle );
599ab47cfaaSmrg
600ab47cfaaSmrg   /* not needed in the server
601ab47cfaaSmrg   if ( drmMap( psav->drmFD,
602ab47cfaaSmrg		pSAVAGEDRIServer->agpTextures.handle,
603ab47cfaaSmrg		pSAVAGEDRIServer->agpTextures.size,
604ab47cfaaSmrg		&pSAVAGEDRIServer->agpTextures.map ) < 0 ) {
605ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
606ab47cfaaSmrg		  "[agp] Could not map agpTextures \n" );
607ab47cfaaSmrg      return FALSE;
608ab47cfaaSmrg   }
609ab47cfaaSmrg
610ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
611ab47cfaaSmrg	       "[agp] agpTextures mapped at 0x%08lx\n",
612ab47cfaaSmrg	       (unsigned long)pSAVAGEDRIServer->agpTextures.map );
613ab47cfaaSmrg   */
614ab47cfaaSmrg
615ab47cfaaSmrg   return TRUE;
616ab47cfaaSmrg}
617ab47cfaaSmrg
618ab47cfaaSmrgstatic Bool SAVAGEDRIMapInit( ScreenPtr pScreen )
619ab47cfaaSmrg{
620ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
621ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
622ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
623ab47cfaaSmrg
624ab47cfaaSmrg   pSAVAGEDRIServer->registers.size = SAVAGEIOMAPSIZE;
625ab47cfaaSmrg
626ab47cfaaSmrg   if ( drmAddMap( psav->drmFD,
627ab47cfaaSmrg		   (drm_handle_t)psav->MmioBase,
628ab47cfaaSmrg		   pSAVAGEDRIServer->registers.size,
629ab47cfaaSmrg		   DRM_REGISTERS,0,
630ab47cfaaSmrg		   &pSAVAGEDRIServer->registers.handle ) < 0 ) {
631ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
632ab47cfaaSmrg		  "[drm] Could not add MMIO registers mapping\n" );
633ab47cfaaSmrg      return FALSE;
634ab47cfaaSmrg   }
635ab47cfaaSmrg
636ab47cfaaSmrg   pSAVAGEDRIServer->aperture.size = 5 * 0x01000000;
637ab47cfaaSmrg
638ab47cfaaSmrg   if ( drmAddMap( psav->drmFD,
639ab47cfaaSmrg		   (drm_handle_t)(psav->ApertureBase),
640ab47cfaaSmrg		   pSAVAGEDRIServer->aperture.size,
641ab47cfaaSmrg		   DRM_FRAME_BUFFER,0,
642ab47cfaaSmrg		   &pSAVAGEDRIServer->aperture.handle ) < 0 ) {
643ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
644ab47cfaaSmrg		  "[drm] Could not add aperture mapping\n" );
645ab47cfaaSmrg      return FALSE;
646ab47cfaaSmrg   }
647ab47cfaaSmrg
648ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
649ab47cfaaSmrg	       "[drm] aperture handle = 0x%08lx\n",
650ab47cfaaSmrg	       pSAVAGEDRIServer->aperture.handle );
651ab47cfaaSmrg
652ab47cfaaSmrg   /*if(drmMap(psav->drmFD,
653ab47cfaaSmrg          pSAVAGEDRIServer->registers.handle,
654ab47cfaaSmrg          pSAVAGEDRIServer->registers.size,
655ab47cfaaSmrg          &pSAVAGEDRIServer->registers.map)<0)
656ab47cfaaSmrg   {
657ab47cfaaSmrg         xf86DrvMsg( pScreen->myNum, X_ERROR,
658ab47cfaaSmrg		  "[drm] Could not map MMIO registers region to virtual\n" );
659ab47cfaaSmrg      return FALSE;
660ab47cfaaSmrg
661ab47cfaaSmrg   }*/
662ab47cfaaSmrg
663ab47cfaaSmrg   if ( !psav->AgpDMA && psav->CommandDMA ) {
664ab47cfaaSmrg       pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE;
665ab47cfaaSmrg       if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->cmdDma.size,
666ab47cfaaSmrg		       DRM_CONSISTENT, DRM_RESTRICTED | DRM_LOCKED |
667ab47cfaaSmrg		       DRM_KERNEL | DRM_WRITE_COMBINING,
668ab47cfaaSmrg		       &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) {
669ab47cfaaSmrg	   psav->CommandDMA = FALSE;
670ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_WARNING,
671ab47cfaaSmrg		       "[drm] Could not add PCI command DMA mapping\n" );
672ab47cfaaSmrg       } else
673ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
674ab47cfaaSmrg		       "[drm] PCI command DMA handle = 0x%08lx\n",
675ab47cfaaSmrg		       pSAVAGEDRIServer->cmdDma.handle );
676ab47cfaaSmrg   }
677ab47cfaaSmrg
678ab47cfaaSmrg   /* Enable ShadowStatus by default for direct rendering. */
679ab47cfaaSmrg   if ( !psav->ShadowStatus && !psav->ForceShadowStatus ) {
680ab47cfaaSmrg       psav->ShadowStatus = TRUE;
681ab47cfaaSmrg       xf86DrvMsg( pScreen->myNum, X_INFO,
682ab47cfaaSmrg		   "[drm] Enabling ShadowStatus for DRI.\n" );
683ab47cfaaSmrg   }
684ab47cfaaSmrg
685ab47cfaaSmrg   /* If shadow status is manually or automatically enabled, use a
686ab47cfaaSmrg    * page in system memory. */
687ab47cfaaSmrg   if ( psav->ShadowStatus ) {
688ab47cfaaSmrg       pSAVAGEDRIServer->status.size = 4096; /* 1 page */
689ab47cfaaSmrg
690ab47cfaaSmrg       if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->status.size,
691ab47cfaaSmrg		       DRM_CONSISTENT, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL,
692ab47cfaaSmrg		       &pSAVAGEDRIServer->status.handle ) < 0 ) {
693ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_ERROR,
694ab47cfaaSmrg		       "[drm] Could not add status page mapping\n" );
695ab47cfaaSmrg	   return FALSE;
696ab47cfaaSmrg       }
697ab47cfaaSmrg       xf86DrvMsg( pScreen->myNum, X_INFO,
698ab47cfaaSmrg		   "[drm] Status handle = 0x%08lx\n",
699ab47cfaaSmrg		   pSAVAGEDRIServer->status.handle );
700ab47cfaaSmrg
701ab47cfaaSmrg       if ( drmMap( psav->drmFD,
702ab47cfaaSmrg		    pSAVAGEDRIServer->status.handle,
703ab47cfaaSmrg		    pSAVAGEDRIServer->status.size,
704ab47cfaaSmrg		    &pSAVAGEDRIServer->status.map ) < 0 ) {
705ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_ERROR,
706ab47cfaaSmrg		       "[drm] Could not map status page\n" );
707ab47cfaaSmrg	   return FALSE;
708ab47cfaaSmrg       }
709ab47cfaaSmrg       xf86DrvMsg( pScreen->myNum, X_INFO,
710ab47cfaaSmrg		   "[drm] Status page mapped at 0x%08lx\n",
711ab47cfaaSmrg		   (unsigned long)pSAVAGEDRIServer->status.map );
712ab47cfaaSmrg
713ab47cfaaSmrg       psav->ShadowPhysical = pSAVAGEDRIServer->status.handle;
714ab47cfaaSmrg       psav->ShadowVirtual = pSAVAGEDRIServer->status.map;
715ab47cfaaSmrg   }
716ab47cfaaSmrg
717ab47cfaaSmrg   return TRUE;
718ab47cfaaSmrg}
719ab47cfaaSmrg
720ab47cfaaSmrgstatic Bool SAVAGEDRIBuffersInit( ScreenPtr pScreen )
721ab47cfaaSmrg{
722ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
723ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
724ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
725ab47cfaaSmrg   int count;
726ab47cfaaSmrg
727ab47cfaaSmrg   if ( !psav->VertexDMA || psav->CommandDMA ) {
728ab47cfaaSmrg       /* At this point psav->CommandDMA == TRUE means that CommandDMA
729ab47cfaaSmrg	* allocation was actually successful. */
730ab47cfaaSmrg       psav->VertexDMA = FALSE;
731ab47cfaaSmrg       return TRUE;
732ab47cfaaSmrg   }
733ab47cfaaSmrg
734ab47cfaaSmrg   if ( psav->AgpDMA ) {
735ab47cfaaSmrg       count = drmAddBufs( psav->drmFD,
736ab47cfaaSmrg			   SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE,
737ab47cfaaSmrg			   DRM_AGP_BUFFER, pSAVAGEDRIServer->buffers.offset );
738ab47cfaaSmrg   } else {
739ab47cfaaSmrg       count = drmAddBufs( psav->drmFD,
740ab47cfaaSmrg			   SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE,
741ab47cfaaSmrg			   0, 0 );
742ab47cfaaSmrg   }
743ab47cfaaSmrg   if ( count <= 0 ) {
744ab47cfaaSmrg       xf86DrvMsg( pScrn->scrnIndex, X_INFO,
745ab47cfaaSmrg		   "[drm] failure adding %d %d byte DMA buffers (%d)\n",
746ab47cfaaSmrg		   SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, count );
747ab47cfaaSmrg       return FALSE;
748ab47cfaaSmrg   }
749ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
750ab47cfaaSmrg	       "[drm] Added %d %d byte DMA buffers\n",
751ab47cfaaSmrg	       count, SAVAGE_BUFFER_SIZE );
752ab47cfaaSmrg
753ab47cfaaSmrg   /* not needed in the server
754ab47cfaaSmrg   pSAVAGEDRIServer->drmBuffers = drmMapBufs( psav->drmFD );
755ab47cfaaSmrg   if ( !pSAVAGEDRIServer->drmBuffers ) {
756ab47cfaaSmrg	xf86DrvMsg( pScreen->myNum, X_ERROR,
757ab47cfaaSmrg		    "[drm] Failed to map DMA buffers list\n" );
758ab47cfaaSmrg	return FALSE;
759ab47cfaaSmrg    }
760ab47cfaaSmrg    xf86DrvMsg( pScreen->myNum, X_INFO,
761ab47cfaaSmrg		"[drm] Mapped %d DMA buffers\n",
762ab47cfaaSmrg		pSAVAGEDRIServer->drmBuffers->count );
763ab47cfaaSmrg   */
764ab47cfaaSmrg
765ab47cfaaSmrg    return TRUE;
766ab47cfaaSmrg}
767ab47cfaaSmrg
768ab47cfaaSmrgstatic Bool SAVAGEDRIKernelInit( ScreenPtr pScreen )
769ab47cfaaSmrg{
770ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
771ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
772ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
773ab47cfaaSmrg   drmSAVAGEInit init;
774ab47cfaaSmrg   int ret;
775ab47cfaaSmrg
776ab47cfaaSmrg   memset( &init, 0, sizeof(drmSAVAGEInit) );
777ab47cfaaSmrg
778ab47cfaaSmrg   init.func = SAVAGE_INIT_BCI;
779ab47cfaaSmrg   init.sarea_priv_offset = sizeof(XF86DRISAREARec);
780ab47cfaaSmrg
781ab47cfaaSmrg   init.cob_size = psav->cobSize/4; /* size in 32-bit entries */
782ab47cfaaSmrg   init.bci_threshold_lo = psav->bciThresholdLo;
783ab47cfaaSmrg   init.bci_threshold_hi = psav->bciThresholdHi;
784ab47cfaaSmrg   init.dma_type = psav->AgpDMA ? SAVAGE_DMA_AGP : SAVAGE_DMA_PCI;
785ab47cfaaSmrg
786ab47cfaaSmrg   init.fb_bpp		= pScrn->bitsPerPixel;
787ab47cfaaSmrg   init.front_offset	= pSAVAGEDRIServer->frontOffset;
788ab47cfaaSmrg   init.front_pitch	= pSAVAGEDRIServer->frontPitch;
789ab47cfaaSmrg   init.back_offset	= pSAVAGEDRIServer->backOffset;
790ab47cfaaSmrg   init.back_pitch	= pSAVAGEDRIServer->backPitch;
791ab47cfaaSmrg
792ab47cfaaSmrg   init.depth_bpp	= pScrn->bitsPerPixel;
793ab47cfaaSmrg   init.depth_offset	= pSAVAGEDRIServer->depthOffset;
794ab47cfaaSmrg   init.depth_pitch	= pSAVAGEDRIServer->depthPitch;
795ab47cfaaSmrg
796ab47cfaaSmrg   init.texture_offset  = pSAVAGEDRIServer->textureOffset;
797ab47cfaaSmrg   init.texture_size    = pSAVAGEDRIServer->textureSize;
798ab47cfaaSmrg
799ab47cfaaSmrg   init.status_offset   = pSAVAGEDRIServer->status.handle;
800ab47cfaaSmrg   init.agp_textures_offset = pSAVAGEDRIServer->agpTextures.handle;
801ab47cfaaSmrg
802ab47cfaaSmrg   /* Savage4-based chips with DRM version >= 2.4 support command DMA,
803ab47cfaaSmrg    * which is preferred because it works with all vertex
804ab47cfaaSmrg    * formats. Command DMA and vertex DMA don't work at the same
805ab47cfaaSmrg    * time. */
806ab47cfaaSmrg   init.buffers_offset = 0;
807ab47cfaaSmrg   init.cmd_dma_offset = 0;
808ab47cfaaSmrg   if ( psav->CommandDMA )
809ab47cfaaSmrg       init.cmd_dma_offset = pSAVAGEDRIServer->cmdDma.handle;
810ab47cfaaSmrg   else if ( psav->VertexDMA )
811ab47cfaaSmrg       init.buffers_offset = pSAVAGEDRIServer->buffers.handle;
812ab47cfaaSmrg
813ab47cfaaSmrg   ret = drmCommandWrite( psav->drmFD, DRM_SAVAGE_BCI_INIT, &init, sizeof(init) );
814ab47cfaaSmrg   if ( ret < 0 ) {
815ab47cfaaSmrg      xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
816ab47cfaaSmrg		  "[drm] Failed to initialize BCI! (%d)\n", ret );
817ab47cfaaSmrg      return FALSE;
818ab47cfaaSmrg   }
819ab47cfaaSmrg
820ab47cfaaSmrg   return TRUE;
821ab47cfaaSmrg}
822ab47cfaaSmrg
823ab47cfaaSmrgBool SAVAGEDRIScreenInit( ScreenPtr pScreen )
824ab47cfaaSmrg{
825ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
826ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
827ab47cfaaSmrg   DRIInfoPtr pDRIInfo;
828ab47cfaaSmrg   SAVAGEDRIPtr pSAVAGEDRI;
829ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer;
830ab47cfaaSmrg
831ab47cfaaSmrg   /* Check that the GLX, DRI, and DRM modules have been loaded by testing
832ab47cfaaSmrg    * for canonical symbols in each module.
833ab47cfaaSmrg    */
834ab47cfaaSmrg   if ( !xf86LoaderCheckSymbol( "GlxSetVisualConfigs" ) )	return FALSE;
835ab47cfaaSmrg   if ( !xf86LoaderCheckSymbol( "drmAvailable" ) )		return FALSE;
836ab47cfaaSmrg   if ( !xf86LoaderCheckSymbol( "DRIQueryVersion" ) ) {
837ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
838ab47cfaaSmrg		  "[dri] SAVAGEDRIScreenInit failed (libdri.a too old)\n" );
839ab47cfaaSmrg      return FALSE;
840ab47cfaaSmrg   }
841ab47cfaaSmrg
842ab47cfaaSmrg   /* Check the DRI version */
843ab47cfaaSmrg   {
844ab47cfaaSmrg      int major, minor, patch;
845ab47cfaaSmrg      DRIQueryVersion( &major, &minor, &patch );
846ab47cfaaSmrg      if ( major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION ) {
847ab47cfaaSmrg         xf86DrvMsg( pScreen->myNum, X_ERROR,
848ab47cfaaSmrg		     "[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n"
849ab47cfaaSmrg		     "[dri] libdri version = %d.%d.%d but version %d.%d.x is needed.\n"
850ab47cfaaSmrg		     "[dri] Disabling the DRI.\n",
851ab47cfaaSmrg		     major, minor, patch,
852ab47cfaaSmrg                     DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION );
853ab47cfaaSmrg         return FALSE;
854ab47cfaaSmrg      }
855ab47cfaaSmrg   }
856ab47cfaaSmrg
857ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
858ab47cfaaSmrg	       "[drm] bpp: %d depth: %d\n",
859ab47cfaaSmrg	       pScrn->bitsPerPixel, pScrn->depth );
860ab47cfaaSmrg
861ab47cfaaSmrg   if ( (pScrn->bitsPerPixel / 8) != 2 &&
862ab47cfaaSmrg	(pScrn->bitsPerPixel / 8) != 4 ) {
863ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
864ab47cfaaSmrg		  "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" );
865ab47cfaaSmrg      return FALSE;
866ab47cfaaSmrg   }
867ab47cfaaSmrg
868ab47cfaaSmrg   pDRIInfo = DRICreateInfoRec();
869ab47cfaaSmrg   if ( !pDRIInfo ) {
870ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
871ab47cfaaSmrg		  "[dri] DRICreateInfoRec() failed\n" );
872ab47cfaaSmrg      return FALSE;
873ab47cfaaSmrg   }
874ab47cfaaSmrg   psav->pDRIInfo = pDRIInfo;
875ab47cfaaSmrg
876ab47cfaaSmrg   pDRIInfo->drmDriverName = SAVAGEKernelDriverName;
877ab47cfaaSmrg   pDRIInfo->clientDriverName = SAVAGEClientDriverName;
878ab47cfaaSmrg   if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
879ab47cfaaSmrg      pDRIInfo->busIdString = DRICreatePCIBusID(psav->PciInfo);
880ab47cfaaSmrg   } else {
881ab47cfaaSmrg      pDRIInfo->busIdString            = xalloc(64);
882ab47cfaaSmrg      sprintf(pDRIInfo->busIdString,
883ab47cfaaSmrg              "PCI:%d:%d:%d",
884ab47cfaaSmrg              psav->PciInfo->bus,
885ab47cfaaSmrg              psav->PciInfo->device,
886ab47cfaaSmrg              psav->PciInfo->func);
887ab47cfaaSmrg   }
888ab47cfaaSmrg   pDRIInfo->ddxDriverMajorVersion = SAVAGE_VERSION_MAJOR;
889ab47cfaaSmrg   pDRIInfo->ddxDriverMinorVersion = SAVAGE_VERSION_MINOR;
890ab47cfaaSmrg   pDRIInfo->ddxDriverPatchVersion = SAVAGE_PATCHLEVEL;
891ab47cfaaSmrg
892ab47cfaaSmrg   pDRIInfo->frameBufferPhysicalAddress = (pointer) psav->FrameBufferBase;
893ab47cfaaSmrg   pDRIInfo->frameBufferSize = psav->videoRambytes;
894ab47cfaaSmrg   pDRIInfo->frameBufferStride = pScrn->displayWidth*(pScrn->bitsPerPixel/8);
895ab47cfaaSmrg   pDRIInfo->ddxDrawableTableEntry = SAVAGE_MAX_DRAWABLES;
896ab47cfaaSmrg
897ab47cfaaSmrg   /* override default DRI block and wakeup handler */
898ab47cfaaSmrg   psav->coreBlockHandler = pDRIInfo->wrap.BlockHandler;
899ab47cfaaSmrg   pDRIInfo->wrap.BlockHandler = SAVAGEBlockHandler;
900ab47cfaaSmrg   psav->coreWakeupHandler = pDRIInfo->wrap.WakeupHandler;
901ab47cfaaSmrg   pDRIInfo->wrap.WakeupHandler = SAVAGEWakeupHandler;
902ab47cfaaSmrg
903ab47cfaaSmrg   pDRIInfo->wrap.ValidateTree = NULL;
904ab47cfaaSmrg   pDRIInfo->wrap.PostValidateTree = NULL;
905ab47cfaaSmrg
906ab47cfaaSmrg   pDRIInfo->createDummyCtx = TRUE;
907ab47cfaaSmrg   pDRIInfo->createDummyCtxPriv = FALSE;
908ab47cfaaSmrg
909ab47cfaaSmrg   if ( SAREA_MAX_DRAWABLES < SAVAGE_MAX_DRAWABLES ) {
910ab47cfaaSmrg      pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
911ab47cfaaSmrg   } else {
912ab47cfaaSmrg      pDRIInfo->maxDrawableTableEntry = SAVAGE_MAX_DRAWABLES;
913ab47cfaaSmrg   }
914ab47cfaaSmrg
915ab47cfaaSmrg   /* For now the mapping works by using a fixed size defined
916ab47cfaaSmrg    * in the SAREA header.
917ab47cfaaSmrg    */
918ab47cfaaSmrg   if ( sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec) > SAREA_MAX ) {
919ab47cfaaSmrg      xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
920ab47cfaaSmrg		  "[drm] Data does not fit in SAREA\n" );
921ab47cfaaSmrg      return FALSE;
922ab47cfaaSmrg   }
923ab47cfaaSmrg
924ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO,
925ab47cfaaSmrg	       "[drm] Sarea %d+%d: %d\n",
926ab47cfaaSmrg	       sizeof(XF86DRISAREARec), sizeof(SAVAGESAREAPrivRec),
927ab47cfaaSmrg	       sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec) );
928ab47cfaaSmrg
929ab47cfaaSmrg   pDRIInfo->SAREASize = SAREA_MAX;
930ab47cfaaSmrg
931ab47cfaaSmrg   pSAVAGEDRI = (SAVAGEDRIPtr)xcalloc( sizeof(SAVAGEDRIRec), 1 );
932ab47cfaaSmrg   if ( !pSAVAGEDRI ) {
933ab47cfaaSmrg      DRIDestroyInfoRec( psav->pDRIInfo );
934ab47cfaaSmrg      psav->pDRIInfo = 0;
935ab47cfaaSmrg      xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
936ab47cfaaSmrg		  "[drm] Failed to allocate memory for private record\n" );
937ab47cfaaSmrg      return FALSE;
938ab47cfaaSmrg   }
939ab47cfaaSmrg
940ab47cfaaSmrg   pSAVAGEDRIServer = (SAVAGEDRIServerPrivatePtr)
941ab47cfaaSmrg      xcalloc( sizeof(SAVAGEDRIServerPrivateRec), 1 );
942ab47cfaaSmrg   if ( !pSAVAGEDRIServer ) {
943ab47cfaaSmrg      xfree( pSAVAGEDRI );
944ab47cfaaSmrg      DRIDestroyInfoRec( psav->pDRIInfo );
945ab47cfaaSmrg      psav->pDRIInfo = 0;
946ab47cfaaSmrg      xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
947ab47cfaaSmrg		  "[drm] Failed to allocate memory for private record\n" );
948ab47cfaaSmrg      return FALSE;
949ab47cfaaSmrg   }
950ab47cfaaSmrg   psav->DRIServerInfo = pSAVAGEDRIServer;
951ab47cfaaSmrg
952ab47cfaaSmrg   pDRIInfo->devPrivate = pSAVAGEDRI;
953ab47cfaaSmrg   pDRIInfo->devPrivateSize = sizeof(SAVAGEDRIRec);
954ab47cfaaSmrg   pDRIInfo->contextSize = sizeof(SAVAGEDRIContextRec);
955ab47cfaaSmrg
956ab47cfaaSmrg   pDRIInfo->CreateContext = SAVAGECreateContext;
957ab47cfaaSmrg   pDRIInfo->DestroyContext = SAVAGEDestroyContext;
958ab47cfaaSmrg
959ab47cfaaSmrg   /* FK: SwapContext is not used with KERNEL_SWAP. */
960ab47cfaaSmrg   pDRIInfo->SwapContext = NULL;
961ab47cfaaSmrg
962ab47cfaaSmrg   pDRIInfo->InitBuffers = SAVAGEDRIInitBuffers;
963ab47cfaaSmrg   pDRIInfo->MoveBuffers = SAVAGEDRIMoveBuffers;
964ab47cfaaSmrg   pDRIInfo->OpenFullScreen = SAVAGEDRIOpenFullScreen;
965ab47cfaaSmrg   pDRIInfo->CloseFullScreen = SAVAGEDRICloseFullScreen;
966ab47cfaaSmrg   pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
967ab47cfaaSmrg
968ab47cfaaSmrg   if ( !DRIScreenInit( pScreen, pDRIInfo, &psav->drmFD ) ) {
969ab47cfaaSmrg      xfree( pSAVAGEDRIServer );
970ab47cfaaSmrg      psav->DRIServerInfo = 0;
971ab47cfaaSmrg      xfree( pDRIInfo->devPrivate );
972ab47cfaaSmrg      pDRIInfo->devPrivate = 0;
973ab47cfaaSmrg      DRIDestroyInfoRec( psav->pDRIInfo );
974ab47cfaaSmrg      psav->pDRIInfo = 0;
975ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
976ab47cfaaSmrg		  "[drm] DRIScreenInit failed.  Disabling DRI.\n" );
977ab47cfaaSmrg      return FALSE;
978ab47cfaaSmrg   }
979ab47cfaaSmrg
980ab47cfaaSmrg   /* Check the SAVAGE DRM version */
981ab47cfaaSmrg   {
982ab47cfaaSmrg      drmVersionPtr version = drmGetVersion(psav->drmFD);
983ab47cfaaSmrg      if ( version ) {
984ab47cfaaSmrg         if ( version->version_major != 2 ||
985ab47cfaaSmrg	      version->version_minor < 0 ) {
986ab47cfaaSmrg            /* incompatible drm version */
987ab47cfaaSmrg            xf86DrvMsg( pScreen->myNum, X_ERROR,
988ab47cfaaSmrg			"[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n"
989ab47cfaaSmrg			"[dri] savage.ko kernel module version is %d.%d.%d but version 2.0.x is needed.\n"
990ab47cfaaSmrg			"[dri] Disabling DRI.\n",
991ab47cfaaSmrg			version->version_major,
992ab47cfaaSmrg			version->version_minor,
993ab47cfaaSmrg			version->version_patchlevel );
994ab47cfaaSmrg            drmFreeVersion( version );
995ab47cfaaSmrg	    SAVAGEDRICloseScreen( pScreen );		/* FIXME: ??? */
996ab47cfaaSmrg            return FALSE;
997ab47cfaaSmrg         }
998ab47cfaaSmrg	 if ( psav->CommandDMA && version->version_minor < 4 ) {
999ab47cfaaSmrg	    xf86DrvMsg( pScreen->myNum, X_WARNING,
1000ab47cfaaSmrg			"[drm] DRM version < 2.4.0 does not support command DMA.\n");
1001ab47cfaaSmrg	    psav->CommandDMA = FALSE;
1002ab47cfaaSmrg	 }
1003ab47cfaaSmrg	 if ( !psav->VertexDMA && version->version_minor < 4 ) {
1004ab47cfaaSmrg	    xf86DrvMsg( pScreen->myNum, X_ERROR,
1005ab47cfaaSmrg			"[drm] DRM version < 2.4.0 requires vertex DMA.\n");
1006ab47cfaaSmrg	    drmFreeVersion( version );
1007ab47cfaaSmrg	    SAVAGEDRICloseScreen( pScreen );
1008ab47cfaaSmrg	    return FALSE;
1009ab47cfaaSmrg	 }
1010ab47cfaaSmrg         drmFreeVersion( version );
1011ab47cfaaSmrg      }
1012ab47cfaaSmrg   }
1013ab47cfaaSmrg
1014ab47cfaaSmrg   if ( !psav->IsPCI && !SAVAGEDRIAgpInit( pScreen ) ) {
1015ab47cfaaSmrg       if (pSAVAGEDRIServer->agp.handle != 0) {
1016ab47cfaaSmrg	   /* AGP initialization succeeded, but adding AGP mappings failed. */
1017ab47cfaaSmrg	   SAVAGEDRICloseScreen( pScreen );
1018ab47cfaaSmrg	   return FALSE;
1019ab47cfaaSmrg       }
1020ab47cfaaSmrg       /* AGP initialization failed, fall back to PCI mode. */
1021ab47cfaaSmrg       psav->IsPCI = TRUE;
1022ab47cfaaSmrg       psav->AgpDMA = FALSE;
1023ab47cfaaSmrg       xf86DrvMsg( pScrn->scrnIndex, X_WARNING,
1024ab47cfaaSmrg		   "[agp] AGP failed to initialize -- falling back to PCI mode.\n");
1025ab47cfaaSmrg       xf86DrvMsg( pScrn->scrnIndex, X_WARNING,
1026ab47cfaaSmrg		   "[agp] Make sure you have the agpgart kernel module loaded.\n");
1027ab47cfaaSmrg   }
1028ab47cfaaSmrg
1029ab47cfaaSmrg   if ( !SAVAGEDRIMapInit( pScreen ) ) {
1030ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1031ab47cfaaSmrg      return FALSE;
1032ab47cfaaSmrg   }
1033ab47cfaaSmrg
1034ab47cfaaSmrg   if ( !SAVAGEDRIBuffersInit( pScreen ) ) {
1035ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1036ab47cfaaSmrg      return FALSE;
1037ab47cfaaSmrg   }
1038ab47cfaaSmrg
1039ab47cfaaSmrg   if ( !SAVAGEInitVisualConfigs( pScreen ) ) {
1040ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1041ab47cfaaSmrg      return FALSE;
1042ab47cfaaSmrg   }
1043ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized\n" );
1044ab47cfaaSmrg
1045ab47cfaaSmrg   return TRUE;
1046ab47cfaaSmrg}
1047ab47cfaaSmrg
1048ab47cfaaSmrg
1049ab47cfaaSmrgBool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen )
1050ab47cfaaSmrg{
1051ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1052ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
1053ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
1054ab47cfaaSmrg   SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
1055ab47cfaaSmrg   int i;
1056ab47cfaaSmrg
1057ab47cfaaSmrg   if ( !psav->pDRIInfo )
1058ab47cfaaSmrg      return FALSE;
1059ab47cfaaSmrg
1060ab47cfaaSmrg   psav->pDRIInfo->driverSwapMethod = DRI_KERNEL_SWAP;
1061ab47cfaaSmrg
1062ab47cfaaSmrg   /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit
1063ab47cfaaSmrg    * because *DRIKernelInit requires that the hardware lock is held by
1064ab47cfaaSmrg    * the X server, and the first time the hardware lock is grabbed is
1065ab47cfaaSmrg    * in DRIFinishScreenInit.
1066ab47cfaaSmrg    */
1067ab47cfaaSmrg   if ( !DRIFinishScreenInit( pScreen ) ) {
1068ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1069ab47cfaaSmrg      return FALSE;
1070ab47cfaaSmrg   }
1071ab47cfaaSmrg   psav->LockHeld = 1;
1072ab47cfaaSmrg
1073ab47cfaaSmrg   if ( !SAVAGEDRIKernelInit( pScreen ) ) {
1074ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1075ab47cfaaSmrg      return FALSE;
1076ab47cfaaSmrg   }
1077ab47cfaaSmrg
1078ab47cfaaSmrg   pSAVAGEDRI->chipset          = psav->Chipset;
1079ab47cfaaSmrg   pSAVAGEDRI->width		= pScrn->virtualX;
1080ab47cfaaSmrg   pSAVAGEDRI->height		= pScrn->virtualY;
1081ab47cfaaSmrg   pSAVAGEDRI->mem		= pScrn->videoRam * 1024;
1082ab47cfaaSmrg   pSAVAGEDRI->cpp		= pScrn->bitsPerPixel / 8;
1083ab47cfaaSmrg   pSAVAGEDRI->zpp		= pSAVAGEDRI->cpp;
1084ab47cfaaSmrg
1085ab47cfaaSmrg   pSAVAGEDRI->agpMode		= psav->IsPCI ? 0 : psav->agpMode;
1086ab47cfaaSmrg
1087ab47cfaaSmrg   pSAVAGEDRI->bufferSize       = SAVAGE_BUFFER_SIZE;
1088ab47cfaaSmrg
1089ab47cfaaSmrg   pSAVAGEDRI->frontOffset		= pSAVAGEDRIServer->frontOffset;
1090ab47cfaaSmrg   pSAVAGEDRI->frontbufferSize		= pSAVAGEDRIServer->frontbufferSize;
1091ab47cfaaSmrg
1092ab47cfaaSmrg   pSAVAGEDRI->backOffset		= pSAVAGEDRIServer->backOffset;
1093ab47cfaaSmrg   pSAVAGEDRI->backbufferSize		= pSAVAGEDRIServer->backbufferSize;
1094ab47cfaaSmrg
1095ab47cfaaSmrg   pSAVAGEDRI->depthOffset		= pSAVAGEDRIServer->depthOffset;
1096ab47cfaaSmrg   pSAVAGEDRI->depthbufferSize		= pSAVAGEDRIServer->depthbufferSize;
1097ab47cfaaSmrg
1098ab47cfaaSmrg   pSAVAGEDRI->textureOffset	= pSAVAGEDRIServer->textureOffset;
1099ab47cfaaSmrg
1100ab47cfaaSmrg   i = mylog2( pSAVAGEDRIServer->textureSize / SAVAGE_NR_TEX_REGIONS );
1101ab47cfaaSmrg   if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE )
1102ab47cfaaSmrg      i = SAVAGE_LOG_MIN_TEX_REGION_SIZE;
1103ab47cfaaSmrg
1104ab47cfaaSmrg   pSAVAGEDRI->logTextureGranularity = i;
1105ab47cfaaSmrg   pSAVAGEDRI->textureSize = (pSAVAGEDRIServer->textureSize >> i) << i; /* truncate */
1106ab47cfaaSmrg
1107ab47cfaaSmrg   pSAVAGEDRI->agpTextureHandle = pSAVAGEDRIServer->agpTextures.handle;
1108ab47cfaaSmrg
1109ab47cfaaSmrg   i = mylog2( pSAVAGEDRIServer->agpTextures.size / SAVAGE_NR_TEX_REGIONS );
1110ab47cfaaSmrg   if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE )
1111ab47cfaaSmrg      i = SAVAGE_LOG_MIN_TEX_REGION_SIZE;
1112ab47cfaaSmrg
1113ab47cfaaSmrg   pSAVAGEDRI->logAgpTextureGranularity = i;
1114ab47cfaaSmrg   pSAVAGEDRI->agpTextureSize = (pSAVAGEDRIServer->agpTextures.size >> i) << i; /* truncate */
1115ab47cfaaSmrg
1116ab47cfaaSmrg   pSAVAGEDRI->apertureHandle	= pSAVAGEDRIServer->aperture.handle;
1117ab47cfaaSmrg   pSAVAGEDRI->apertureSize	= pSAVAGEDRIServer->aperture.size;
1118ab47cfaaSmrg   {
1119ab47cfaaSmrg      unsigned int shift = 0;
1120ab47cfaaSmrg
1121ab47cfaaSmrg      if(pSAVAGEDRI->width > 1024)
1122ab47cfaaSmrg        shift = 1;
1123ab47cfaaSmrg
1124ab47cfaaSmrg      pSAVAGEDRI->aperturePitch = psav->ulAperturePitch;
1125ab47cfaaSmrg   }
1126ab47cfaaSmrg
1127ab47cfaaSmrg   {
1128ab47cfaaSmrg      unsigned int value = 0;
1129ab47cfaaSmrg
1130ab47cfaaSmrg      OUTREG(0x850C,(INREG(0x850C) | 0x00008000)); /* AGD: I don't think this does anything on 3D/MX/IX */
1131ab47cfaaSmrg						   /* maybe savage4 too... */
1132ab47cfaaSmrg      /* we don't use Y range flag,so comment it */
1133ab47cfaaSmrg      /*
1134ab47cfaaSmrg        if(pSAVAGEDRI->width <= 1024)
1135ab47cfaaSmrg            value |= (1<<29);
1136ab47cfaaSmrg      */
1137ab47cfaaSmrg      if ((psav->Chipset == S3_SAVAGE_MX) /* 3D/MX/IX seem to set up the tile stride differently */
1138ab47cfaaSmrg	|| (psav->Chipset == S3_SAVAGE3D)) {
1139ab47cfaaSmrg      	    if(pSAVAGEDRI->cpp == 2)
1140ab47cfaaSmrg      	    {
1141ab47cfaaSmrg         	value |=  ((psav->lDelta / 4) >> 5) << 24;
1142ab47cfaaSmrg         	value |= 2<<30;
1143ab47cfaaSmrg      	    } else {
1144ab47cfaaSmrg         	value |=  ((psav->lDelta / 4) >> 5) << 24;
1145ab47cfaaSmrg         	value |= 3<<30;
1146ab47cfaaSmrg      	    }
1147ab47cfaaSmrg
1148ab47cfaaSmrg	    OUTREG(TILED_SURFACE_REGISTER_0, value|(pSAVAGEDRI->frontOffset) ); /* front */
1149ab47cfaaSmrg	    OUTREG(TILED_SURFACE_REGISTER_1, value|(pSAVAGEDRI->backOffset) ); /* back  */
1150ab47cfaaSmrg	    OUTREG(TILED_SURFACE_REGISTER_2, value|(pSAVAGEDRI->depthOffset) ); /* depth */
1151ab47cfaaSmrg      } else {
1152ab47cfaaSmrg	    int offset_shift = 5;
1153ab47cfaaSmrg      	    if(pSAVAGEDRI->cpp == 2)
1154ab47cfaaSmrg      	    {
1155ab47cfaaSmrg         	value |=  (((pSAVAGEDRI->width + 0x3F) & 0xFFC0) >> 6) << 20;
1156ab47cfaaSmrg         	value |= 2<<30;
1157ab47cfaaSmrg      	    } else {
1158ab47cfaaSmrg         	value |=  (((pSAVAGEDRI->width + 0x1F) & 0xFFE0) >> 5) << 20;
1159ab47cfaaSmrg         	value |= 3<<30;
1160ab47cfaaSmrg      	    }
1161ab47cfaaSmrg	    if (psav->Chipset == S3_SUPERSAVAGE) /* supersavages have a different shift */
1162ab47cfaaSmrg		offset_shift = 6;
1163ab47cfaaSmrg	    OUTREG(TILED_SURFACE_REGISTER_0, value|(pSAVAGEDRI->frontOffset >> offset_shift) ); /* front */
1164ab47cfaaSmrg	    OUTREG(TILED_SURFACE_REGISTER_1, value|(pSAVAGEDRI->backOffset >> offset_shift) ); /* back  */
1165ab47cfaaSmrg	    OUTREG(TILED_SURFACE_REGISTER_2, value|(pSAVAGEDRI->depthOffset >> offset_shift) ); /* depth */
1166ab47cfaaSmrg      }
1167ab47cfaaSmrg   }
1168ab47cfaaSmrg
1169ab47cfaaSmrg   pSAVAGEDRI->statusHandle	= pSAVAGEDRIServer->status.handle;
1170ab47cfaaSmrg   pSAVAGEDRI->statusSize	= pSAVAGEDRIServer->status.size;
1171ab47cfaaSmrg
1172ab47cfaaSmrg   pSAVAGEDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
1173ab47cfaaSmrg
1174ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRIServer:\n" );
1175ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	reserved_map_agpstart:0x%08x\n",pSAVAGEDRIServer->reserved_map_agpstart);
1176ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	reserved_map_idx:0x%08x\n",pSAVAGEDRIServer->reserved_map_idx);
1177ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	sarea_priv_offset:0x%08x\n",pSAVAGEDRIServer->sarea_priv_offset);
1178ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	chipset:0x%08x\n",pSAVAGEDRIServer->chipset);
1179ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	sgram:0x%08x\n",pSAVAGEDRIServer->sgram);
1180ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontbufferSize:0x%08x\n",pSAVAGEDRIServer->frontbufferSize);
1181ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontOffset:0x%08x\n",pSAVAGEDRIServer->frontOffset);
1182ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontPitch:0x%08x\n",pSAVAGEDRIServer->frontPitch);
1183ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backbufferSize:0x%08x\n",pSAVAGEDRIServer->backbufferSize);
1184ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backOffset:0x%08x\n",pSAVAGEDRIServer->backOffset);
1185ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backPitch:0x%08x\n",pSAVAGEDRIServer->backPitch);
1186ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthbufferSize:0x%08x\n",pSAVAGEDRIServer->depthbufferSize);
1187ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthOffset:0x%08x\n",pSAVAGEDRIServer->depthOffset);
1188ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthPitch:0x%08x\n",pSAVAGEDRIServer->depthPitch);
1189ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureOffset:0x%08x\n",pSAVAGEDRIServer->textureOffset);
1190ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize);
1191ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize);
1192ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	logTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logTextureGranularity);
1193ab47cfaaSmrg
1194ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agp:handle:0x%08lx\n",pSAVAGEDRIServer->agp.handle);
1195ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agp:offset:0x%08x\n",pSAVAGEDRIServer->agp.offset);
1196ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agp:size:0x%08x\n",pSAVAGEDRIServer->agp.size);
1197ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agp:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agp.map);
1198ab47cfaaSmrg
1199ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	registers:handle:0x%08lx\n",pSAVAGEDRIServer->registers.handle);
1200ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	registers:offset:0x%08x\n",pSAVAGEDRIServer->registers.offset);
1201ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	registers:size:0x%08x\n",pSAVAGEDRIServer->registers.size);
1202ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	registers:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->registers.map);
1203ab47cfaaSmrg
1204ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	status:handle:0x%08lx\n",pSAVAGEDRIServer->status.handle);
1205ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	status:offset:0x%08x\n",pSAVAGEDRIServer->status.offset);
1206ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	status:size:0x%08x\n",pSAVAGEDRIServer->status.size);
1207ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	status:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->status.map);
1208ab47cfaaSmrg
1209ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextures:handle:0x%08lx\n",pSAVAGEDRIServer->agpTextures.handle);
1210ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextures:offset:0x%08x\n",pSAVAGEDRIServer->agpTextures.offset);
1211ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextures:size:0x%08x\n",pSAVAGEDRIServer->agpTextures.size);
1212ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	apgTextures:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agpTextures.map);
1213ab47cfaaSmrg
1214ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	logAgpTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logAgpTextureGranularity);
1215ab47cfaaSmrg
1216ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cmdDma:handle:0x%08lx\n",pSAVAGEDRIServer->cmdDma.handle);
1217ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cmdDma:offset:0x%08x\n",pSAVAGEDRIServer->cmdDma.offset);
1218ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cmdDma:size:0x%08x\n",pSAVAGEDRIServer->cmdDma.size);
1219ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cmdDma:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->cmdDma.map);
1220ab47cfaaSmrg
1221ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRI:\n" );
1222ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	chipset:0x%08x\n",pSAVAGEDRI->chipset );
1223ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	width:0x%08x\n",pSAVAGEDRI->width );
1224ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	height:0x%08x\n",pSAVAGEDRI->height );
1225ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	mem:0x%08x\n",pSAVAGEDRI->mem );
1226ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cpp:%d\n",pSAVAGEDRI->cpp );
1227ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	zpp:%d\n",pSAVAGEDRI->zpp );
1228ab47cfaaSmrg
1229ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpMode:%d\n",pSAVAGEDRI->agpMode );
1230ab47cfaaSmrg
1231ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	bufferSize:%u\n",pSAVAGEDRI->bufferSize );
1232ab47cfaaSmrg
1233ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontbufferSize:0x%08x\n",pSAVAGEDRI->frontbufferSize);
1234ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontOffset:0x%08x\n",pSAVAGEDRI->frontOffset );
1235ab47cfaaSmrg
1236ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backbufferSize:0x%08x\n",pSAVAGEDRI->backbufferSize);
1237ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backOffset:0x%08x\n",pSAVAGEDRI->backOffset );
1238ab47cfaaSmrg
1239ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthbufferSize:0x%08x\n",pSAVAGEDRI->depthbufferSize);
1240ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthOffset:0x%08x\n",pSAVAGEDRI->depthOffset );
1241ab47cfaaSmrg
1242ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureOffset:0x%08x\n",pSAVAGEDRI->textureOffset );
1243ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureSize:0x%08x\n",pSAVAGEDRI->textureSize );
1244ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	logTextureGranularity:0x%08x\n",pSAVAGEDRI->logTextureGranularity );
1245ab47cfaaSmrg
1246ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextureHandle:0x%08lx\n",pSAVAGEDRI->agpTextureHandle );
1247ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextureSize:0x%08x\n",pSAVAGEDRI->agpTextureSize );
1248ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	logAgpTextureGranularity:0x%08x\n",pSAVAGEDRI->logAgpTextureGranularity );
1249ab47cfaaSmrg
1250ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	apertureHandle:0x%08lx\n",pSAVAGEDRI->apertureHandle);
1251ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	apertureSize:0x%08x\n",pSAVAGEDRI->apertureSize);
1252ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	aperturePitch:0x%08x\n",pSAVAGEDRI->aperturePitch);
1253ab47cfaaSmrg
1254ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	statusHandle:0x%08lx\n",pSAVAGEDRI->statusHandle);
1255ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	statusSize:0x%08x\n",pSAVAGEDRI->statusSize);
1256ab47cfaaSmrg
1257ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	sarea_priv_offset:0x%08x\n",pSAVAGEDRI->sarea_priv_offset);
1258ab47cfaaSmrg
1259ab47cfaaSmrg   return TRUE;
1260ab47cfaaSmrg}
1261ab47cfaaSmrg
1262ab47cfaaSmrg
1263ab47cfaaSmrgvoid SAVAGEDRICloseScreen( ScreenPtr pScreen )
1264ab47cfaaSmrg{
1265ab47cfaaSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1266ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
1267ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
1268ab47cfaaSmrg
1269ab47cfaaSmrg   if ( pSAVAGEDRIServer->status.map ) {
1270ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->status.map, pSAVAGEDRIServer->status.size );
1271ab47cfaaSmrg      pSAVAGEDRIServer->status.map = NULL;
1272ab47cfaaSmrg   }
1273ab47cfaaSmrg
1274ab47cfaaSmrg   if ( pSAVAGEDRIServer->registers.map ) {
1275ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->registers.map, pSAVAGEDRIServer->registers.size );
1276ab47cfaaSmrg      pSAVAGEDRIServer->registers.map = NULL;
1277ab47cfaaSmrg   }
1278ab47cfaaSmrg
1279ab47cfaaSmrg   if ( pSAVAGEDRIServer->aperture.map ) {
1280ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->aperture.map, pSAVAGEDRIServer->aperture.size );
1281ab47cfaaSmrg      pSAVAGEDRIServer->aperture.map = NULL;
1282ab47cfaaSmrg   }
1283ab47cfaaSmrg
1284ab47cfaaSmrg   if ( pSAVAGEDRIServer->agpTextures.map ) {
1285ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->agpTextures.map,
1286ab47cfaaSmrg                pSAVAGEDRIServer->agpTextures.size );
1287ab47cfaaSmrg      pSAVAGEDRIServer->agpTextures.map = NULL;
1288ab47cfaaSmrg   }
1289ab47cfaaSmrg
1290ab47cfaaSmrg   if (pSAVAGEDRIServer->status.handle)
1291ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->status.handle);
1292ab47cfaaSmrg
1293ab47cfaaSmrg   if (pSAVAGEDRIServer->registers.handle)
1294ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle);
1295ab47cfaaSmrg
1296ab47cfaaSmrg   if (pSAVAGEDRIServer->aperture.handle)
1297ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle);
1298ab47cfaaSmrg
1299ab47cfaaSmrg   if (pSAVAGEDRIServer->agpTextures.handle)
1300ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->agpTextures.handle);
1301ab47cfaaSmrg
1302ab47cfaaSmrg   if (pSAVAGEDRIServer->cmdDma.handle)
1303ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->cmdDma.handle);
1304ab47cfaaSmrg
1305ab47cfaaSmrg   if ( pSAVAGEDRIServer->buffers.map ) {
1306ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->buffers.map, pSAVAGEDRIServer->buffers.size );
1307ab47cfaaSmrg      pSAVAGEDRIServer->buffers.map = NULL;
1308ab47cfaaSmrg   }
1309ab47cfaaSmrg
1310ab47cfaaSmrg   if ( pSAVAGEDRIServer->agp.handle ) {
1311ab47cfaaSmrg      drmAgpUnbind( psav->drmFD, pSAVAGEDRIServer->agp.handle );
1312ab47cfaaSmrg      drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle );
1313ab47cfaaSmrg      pSAVAGEDRIServer->agp.handle = 0;
1314ab47cfaaSmrg      drmAgpRelease( psav->drmFD );
1315ab47cfaaSmrg   }
1316ab47cfaaSmrg
1317ab47cfaaSmrg   DRICloseScreen( pScreen );
1318ab47cfaaSmrg
1319ab47cfaaSmrg   /* Don't use shadow status any more. If this happens due to failed
1320ab47cfaaSmrg    * DRI initialization then SavageScreenInit will do the real
1321ab47cfaaSmrg    * cleanup and restore ShadowStatus to sane settings. */
1322ab47cfaaSmrg   psav->ShadowVirtual = NULL;
1323ab47cfaaSmrg   psav->ShadowPhysical = 0;
1324ab47cfaaSmrg
1325ab47cfaaSmrg   if(psav->reserved)
1326ab47cfaaSmrg      xf86FreeOffscreenLinear(psav->reserved);
1327ab47cfaaSmrg
1328ab47cfaaSmrg   if ( psav->pDRIInfo ) {
1329ab47cfaaSmrg      if ( psav->pDRIInfo->devPrivate ) {
1330ab47cfaaSmrg	 xfree( psav->pDRIInfo->devPrivate );
1331ab47cfaaSmrg	 psav->pDRIInfo->devPrivate = 0;
1332ab47cfaaSmrg      }
1333ab47cfaaSmrg      DRIDestroyInfoRec( psav->pDRIInfo );
1334ab47cfaaSmrg      psav->pDRIInfo = 0;
1335ab47cfaaSmrg   }
1336ab47cfaaSmrg   if ( psav->DRIServerInfo ) {
1337ab47cfaaSmrg      xfree( psav->DRIServerInfo );
1338ab47cfaaSmrg      psav->DRIServerInfo = 0;
1339ab47cfaaSmrg   }
1340ab47cfaaSmrg   if ( psav->pVisualConfigs ) {
1341ab47cfaaSmrg      xfree( psav->pVisualConfigs );
1342ab47cfaaSmrg   }
1343ab47cfaaSmrg   if ( psav->pVisualConfigsPriv ) {
1344ab47cfaaSmrg      xfree( psav->pVisualConfigsPriv );
1345ab47cfaaSmrg   }
1346ab47cfaaSmrg}
1347ab47cfaaSmrg
1348ab47cfaaSmrgvoid
1349ab47cfaaSmrgSAVAGEDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
1350ab47cfaaSmrg{
1351ab47cfaaSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
1352ab47cfaaSmrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1353ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1354ab47cfaaSmrg    BoxPtr pbox = REGION_RECTS(prgn);
1355ab47cfaaSmrg    int nbox  = REGION_NUM_RECTS(prgn);
1356ab47cfaaSmrg    drmSAVAGECmdHeader cmd[2];
1357ab47cfaaSmrg    drmSAVAGECmdbuf cmdBuf;
1358ab47cfaaSmrg    int ret;
1359ab47cfaaSmrg
1360ab47cfaaSmrg    if (!psav->LockHeld) {
1361ab47cfaaSmrg	xf86DrvMsg( pScrn->scrnIndex, X_WARNING,
1362ab47cfaaSmrg		    "Not holding the lock in InitBuffers.\n");
1363ab47cfaaSmrg	return;
1364ab47cfaaSmrg    }
1365ab47cfaaSmrg
1366ab47cfaaSmrg    cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR;
1367ab47cfaaSmrg    cmd[0].clear0.flags = SAVAGE_BACK|SAVAGE_DEPTH;
1368ab47cfaaSmrg    cmd[1].clear1.mask = 0xffffffff;
1369ab47cfaaSmrg    cmd[1].clear1.value = 0;
1370ab47cfaaSmrg
1371ab47cfaaSmrg    cmdBuf.cmd_addr = cmd;
1372ab47cfaaSmrg    cmdBuf.size = 2;
1373ab47cfaaSmrg    cmdBuf.dma_idx = 0;
1374ab47cfaaSmrg    cmdBuf.discard = 0;
1375ab47cfaaSmrg    cmdBuf.vb_addr = NULL;
1376ab47cfaaSmrg    cmdBuf.vb_size = 0;
1377ab47cfaaSmrg    cmdBuf.vb_stride = 0;
1378ab47cfaaSmrg    cmdBuf.box_addr = (drm_clip_rect_t*)pbox;
1379ab47cfaaSmrg    cmdBuf.nbox = nbox;
1380ab47cfaaSmrg
1381ab47cfaaSmrg    ret = drmCommandWrite(psav->drmFD, DRM_SAVAGE_BCI_CMDBUF,
1382ab47cfaaSmrg			  &cmdBuf, sizeof(cmdBuf));
1383ab47cfaaSmrg    if (ret < 0) {
1384ab47cfaaSmrg	xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
1385ab47cfaaSmrg		    "SAVAGEDRIInitBuffers: drmCommandWrite returned %d.\n",
1386ab47cfaaSmrg		    ret);
1387ab47cfaaSmrg    }
1388ab47cfaaSmrg}
1389ab47cfaaSmrg
1390ab47cfaaSmrg/*
1391ab47cfaaSmrg  This routine is a modified form of XAADoBitBlt with the calls to
1392ab47cfaaSmrg  ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
1393ab47cfaaSmrg  instead of destination. My origin is upside down so the ydir cases
1394ab47cfaaSmrg  are reversed.
1395ab47cfaaSmrg*/
1396ab47cfaaSmrg
1397ab47cfaaSmrgvoid
1398ab47cfaaSmrgSAVAGEDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
1399ab47cfaaSmrg		   RegionPtr prgnSrc, CARD32 index)
1400ab47cfaaSmrg{
1401ab47cfaaSmrg    ScreenPtr pScreen = pParent->drawable.pScreen;
1402ab47cfaaSmrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1403ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1404ab47cfaaSmrg    int nbox;
1405ab47cfaaSmrg    BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
1406ab47cfaaSmrg    DDXPointPtr pptTmp, pptNew1, pptNew2;
1407ab47cfaaSmrg    int xdir, ydir;
1408ab47cfaaSmrg    int dx, dy;
1409ab47cfaaSmrg    DDXPointPtr pptSrc;
1410ab47cfaaSmrg    int screenwidth = pScrn->virtualX;
1411ab47cfaaSmrg    int screenheight = pScrn->virtualY;
1412ab47cfaaSmrg    BCI_GET_PTR;
1413ab47cfaaSmrg
1414ab47cfaaSmrg    if (!psav->LockHeld) {
1415ab47cfaaSmrg	xf86DrvMsg( pScrn->scrnIndex, X_INFO, "Not holding lock in MoveBuffers\n");
1416ab47cfaaSmrg    }
1417ab47cfaaSmrg
1418ab47cfaaSmrg    pbox = REGION_RECTS(prgnSrc);
1419ab47cfaaSmrg    nbox = REGION_NUM_RECTS(prgnSrc);
1420ab47cfaaSmrg    pboxNew1 = 0;
1421ab47cfaaSmrg    pptNew1 = 0;
1422ab47cfaaSmrg    pboxNew2 = 0;
1423ab47cfaaSmrg    pboxNew2 = 0;
1424ab47cfaaSmrg    pptSrc = &ptOldOrg;
1425ab47cfaaSmrg
1426ab47cfaaSmrg    dx = pParent->drawable.x - ptOldOrg.x;
1427ab47cfaaSmrg    dy = pParent->drawable.y - ptOldOrg.y;
1428ab47cfaaSmrg
1429ab47cfaaSmrg    /* If the copy will overlap in Y, reverse the order */
1430ab47cfaaSmrg    if (dy>0) {
1431ab47cfaaSmrg        ydir = -1;
1432ab47cfaaSmrg
1433ab47cfaaSmrg        if (nbox>1) {
1434ab47cfaaSmrg	    /* Keep ordering in each band, reverse order of bands */
1435ab47cfaaSmrg	    pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
1436ab47cfaaSmrg	    if (!pboxNew1) return;
1437ab47cfaaSmrg	    pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
1438ab47cfaaSmrg	    if (!pptNew1) {
1439ab47cfaaSmrg	        DEALLOCATE_LOCAL(pboxNew1);
1440ab47cfaaSmrg	        return;
1441ab47cfaaSmrg	    }
1442ab47cfaaSmrg	    pboxBase = pboxNext = pbox+nbox-1;
1443ab47cfaaSmrg	    while (pboxBase >= pbox) {
1444ab47cfaaSmrg	        while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
1445ab47cfaaSmrg		  pboxNext--;
1446ab47cfaaSmrg	        pboxTmp = pboxNext+1;
1447ab47cfaaSmrg	        pptTmp = pptSrc + (pboxTmp - pbox);
1448ab47cfaaSmrg	        while (pboxTmp <= pboxBase) {
1449ab47cfaaSmrg		    *pboxNew1++ = *pboxTmp++;
1450ab47cfaaSmrg		    *pptNew1++ = *pptTmp++;
1451ab47cfaaSmrg		}
1452ab47cfaaSmrg	        pboxBase = pboxNext;
1453ab47cfaaSmrg	    }
1454ab47cfaaSmrg	    pboxNew1 -= nbox;
1455ab47cfaaSmrg	    pbox = pboxNew1;
1456ab47cfaaSmrg	    pptNew1 -= nbox;
1457ab47cfaaSmrg	    pptSrc = pptNew1;
1458ab47cfaaSmrg	}
1459ab47cfaaSmrg    } else {
1460ab47cfaaSmrg        /* No changes required */
1461ab47cfaaSmrg        ydir = 1;
1462ab47cfaaSmrg    }
1463ab47cfaaSmrg
1464ab47cfaaSmrg    /* If the regions will overlap in X, reverse the order */
1465ab47cfaaSmrg    if (dx>0) {
1466ab47cfaaSmrg        xdir = -1;
1467ab47cfaaSmrg
1468ab47cfaaSmrg        if (nbox > 1) {
1469ab47cfaaSmrg	    /*reverse orderof rects in each band */
1470ab47cfaaSmrg	    pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
1471ab47cfaaSmrg	    pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
1472ab47cfaaSmrg	    if (!pboxNew2 || !pptNew2) {
1473ab47cfaaSmrg	        if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
1474ab47cfaaSmrg	        if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
1475ab47cfaaSmrg	        if (pboxNew1) {
1476ab47cfaaSmrg		    DEALLOCATE_LOCAL(pptNew1);
1477ab47cfaaSmrg		    DEALLOCATE_LOCAL(pboxNew1);
1478ab47cfaaSmrg		}
1479ab47cfaaSmrg	       return;
1480ab47cfaaSmrg	    }
1481ab47cfaaSmrg	    pboxBase = pboxNext = pbox;
1482ab47cfaaSmrg	    while (pboxBase < pbox+nbox) {
1483ab47cfaaSmrg	        while ((pboxNext < pbox+nbox) &&
1484ab47cfaaSmrg		       (pboxNext->y1 == pboxBase->y1))
1485ab47cfaaSmrg		  pboxNext++;
1486ab47cfaaSmrg	        pboxTmp = pboxNext;
1487ab47cfaaSmrg	        pptTmp = pptSrc + (pboxTmp - pbox);
1488ab47cfaaSmrg	        while (pboxTmp != pboxBase) {
1489ab47cfaaSmrg		    *pboxNew2++ = *--pboxTmp;
1490ab47cfaaSmrg		    *pptNew2++ = *--pptTmp;
1491ab47cfaaSmrg		}
1492ab47cfaaSmrg	        pboxBase = pboxNext;
1493ab47cfaaSmrg	    }
1494ab47cfaaSmrg	    pboxNew2 -= nbox;
1495ab47cfaaSmrg	    pbox = pboxNew2;
1496ab47cfaaSmrg	    pptNew2 -= nbox;
1497ab47cfaaSmrg	    pptSrc = pptNew2;
1498ab47cfaaSmrg	}
1499ab47cfaaSmrg    } else {
1500ab47cfaaSmrg        /* No changes are needed */
1501ab47cfaaSmrg        xdir = 1;
1502ab47cfaaSmrg    }
1503ab47cfaaSmrg
1504ab47cfaaSmrg    BCI_SEND(0xc0030000); /* wait for 2D+3D idle */
1505ab47cfaaSmrg    SAVAGEDRISetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1);
1506ab47cfaaSmrg    for ( ; nbox-- ; pbox++)
1507ab47cfaaSmrg     {
1508ab47cfaaSmrg	 int x1 = pbox->x1;
1509ab47cfaaSmrg	 int y1 = pbox->y1;
1510ab47cfaaSmrg	 int destx = x1 + dx;
1511ab47cfaaSmrg	 int desty = y1 + dy;
1512ab47cfaaSmrg	 int w = pbox->x2 - x1 + 1;
1513ab47cfaaSmrg	 int h = pbox->y2 - y1 + 1;
1514ab47cfaaSmrg
1515ab47cfaaSmrg	 if ( destx < 0 ) x1 -= destx, w += destx, destx = 0;
1516ab47cfaaSmrg	 if ( desty < 0 ) y1 -= desty, h += desty, desty = 0;
1517ab47cfaaSmrg	 if ( destx + w > screenwidth ) w = screenwidth - destx;
1518ab47cfaaSmrg	 if ( desty + h > screenheight ) h = screenheight - desty;
1519ab47cfaaSmrg	 if ( w <= 0 ) continue;
1520ab47cfaaSmrg	 if ( h <= 0 ) continue;
1521ab47cfaaSmrg
1522ab47cfaaSmrg	 SAVAGESelectBuffer(pScrn, SAVAGE_BACK);
1523ab47cfaaSmrg	 SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1, y1,
1524ab47cfaaSmrg					       destx,desty, w, h);
1525ab47cfaaSmrg	 SAVAGESelectBuffer(pScrn, SAVAGE_DEPTH);
1526ab47cfaaSmrg	 SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1,y1,
1527ab47cfaaSmrg					       destx,desty, w, h);
1528ab47cfaaSmrg     }
1529ab47cfaaSmrg    SAVAGESelectBuffer(pScrn, SAVAGE_FRONT);
1530ab47cfaaSmrg
1531ab47cfaaSmrg    if (pboxNew2) {
1532ab47cfaaSmrg        DEALLOCATE_LOCAL(pptNew2);
1533ab47cfaaSmrg        DEALLOCATE_LOCAL(pboxNew2);
1534ab47cfaaSmrg    }
1535ab47cfaaSmrg    if (pboxNew1) {
1536ab47cfaaSmrg        DEALLOCATE_LOCAL(pptNew1);
1537ab47cfaaSmrg        DEALLOCATE_LOCAL(pboxNew1);
1538ab47cfaaSmrg    }
1539ab47cfaaSmrg
1540ab47cfaaSmrg    BCI_SEND(0xc0020000); /* wait for 2D idle */
1541ab47cfaaSmrg    if (psav->useEXA)
1542ab47cfaaSmrg	exaMarkSync(pScreen);
1543ab47cfaaSmrg    else
1544ab47cfaaSmrg	psav->AccelInfoRec->NeedToSync = TRUE;
1545ab47cfaaSmrg}
1546ab47cfaaSmrg
1547ab47cfaaSmrgstatic void
1548ab47cfaaSmrgSAVAGEDRISetupForScreenToScreenCopy(
1549ab47cfaaSmrg    ScrnInfoPtr pScrn,
1550ab47cfaaSmrg    int xdir,
1551ab47cfaaSmrg    int ydir,
1552ab47cfaaSmrg    int rop,
1553ab47cfaaSmrg    unsigned planemask,
1554ab47cfaaSmrg    int transparency_color)
1555ab47cfaaSmrg{
1556ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1557ab47cfaaSmrg    int cmd =0;
1558ab47cfaaSmrg
1559ab47cfaaSmrg    cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD | BCI_CMD_SRC_PBD_COLOR;
1560ab47cfaaSmrg    BCI_CMD_SET_ROP( cmd, XAAGetCopyROP(rop) );
1561ab47cfaaSmrg    if (transparency_color != -1)
1562ab47cfaaSmrg        cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT;
1563ab47cfaaSmrg
1564ab47cfaaSmrg    if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP;
1565ab47cfaaSmrg    if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP;
1566ab47cfaaSmrg
1567ab47cfaaSmrg    psav->SavedBciCmd = cmd;
1568ab47cfaaSmrg    psav->SavedBgColor = transparency_color;
1569ab47cfaaSmrg
1570ab47cfaaSmrg}
1571ab47cfaaSmrg
1572ab47cfaaSmrgstatic void
1573ab47cfaaSmrgSAVAGEDRISubsequentScreenToScreenCopy(
1574ab47cfaaSmrg    ScrnInfoPtr pScrn,
1575ab47cfaaSmrg    int x1,
1576ab47cfaaSmrg    int y1,
1577ab47cfaaSmrg    int x2,
1578ab47cfaaSmrg    int y2,
1579ab47cfaaSmrg    int w,
1580ab47cfaaSmrg    int h)
1581ab47cfaaSmrg{
1582ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1583ab47cfaaSmrg    BCI_GET_PTR;
1584ab47cfaaSmrg
1585ab47cfaaSmrg    if (!w || !h) return;
1586ab47cfaaSmrg    if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) {
1587ab47cfaaSmrg        w --;
1588ab47cfaaSmrg        x1 += w;
1589ab47cfaaSmrg        x2 += w;
1590ab47cfaaSmrg        w ++;
1591ab47cfaaSmrg    }
1592ab47cfaaSmrg    if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) {
1593ab47cfaaSmrg        h --;
1594ab47cfaaSmrg        y1 += h;
1595ab47cfaaSmrg        y2 += h;
1596ab47cfaaSmrg        h ++;
1597ab47cfaaSmrg    }
1598ab47cfaaSmrg
1599ab47cfaaSmrg    psav->WaitQueue(psav,6);
1600ab47cfaaSmrg    BCI_SEND(psav->SavedBciCmd);
1601ab47cfaaSmrg    if (psav->SavedBgColor != -1)
1602ab47cfaaSmrg	BCI_SEND(psav->SavedBgColor);
1603ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x1, y1));
1604ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x2, y2));
1605ab47cfaaSmrg    BCI_SEND(BCI_W_H(w, h));
1606ab47cfaaSmrg
1607ab47cfaaSmrg}
1608ab47cfaaSmrg
1609ab47cfaaSmrg/*
1610ab47cfaaSmrg * the FullScreen DRI code is dead, this is just left in place to show how
1611ab47cfaaSmrg * to set up pageflipping.
1612ab47cfaaSmrg */
1613ab47cfaaSmrgstatic Bool
1614ab47cfaaSmrgSAVAGEDRIOpenFullScreen(ScreenPtr pScreen)
1615ab47cfaaSmrg{
1616ab47cfaaSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1617ab47cfaaSmrg  vgaHWPtr hwp = VGAHWPTR(pScrn);
1618ab47cfaaSmrg  SavagePtr psav = SAVPTR(pScrn);
1619ab47cfaaSmrg  unsigned int vgaCRIndex = hwp->IOBase + 4;
1620ab47cfaaSmrg  unsigned int vgaCRReg = hwp->IOBase + 5;
1621ab47cfaaSmrg  SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
1622ab47cfaaSmrg  unsigned int TileStride;
1623ab47cfaaSmrg  unsigned int WidthinTiles;
1624ab47cfaaSmrg  unsigned int depth;
1625ab47cfaaSmrg
1626ab47cfaaSmrg  OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7);
1627ab47cfaaSmrg  /*VGAOUT8(vgaCRIndex,0x66);
1628ab47cfaaSmrg  VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg)|0x10);*/
1629ab47cfaaSmrg  VGAOUT8(vgaCRIndex,0x69);
1630ab47cfaaSmrg  VGAOUT8(vgaCRReg, 0x80);
1631ab47cfaaSmrg
1632ab47cfaaSmrg  depth = pScrn->bitsPerPixel;
1633ab47cfaaSmrg
1634ab47cfaaSmrg  if(depth == 16)
1635ab47cfaaSmrg  {
1636ab47cfaaSmrg      WidthinTiles = (pSAVAGEDRI->width+63)>>6;
1637ab47cfaaSmrg      TileStride = (pSAVAGEDRI->width+63)&(~63);
1638ab47cfaaSmrg
1639ab47cfaaSmrg  }
1640ab47cfaaSmrg  else
1641ab47cfaaSmrg  {
1642ab47cfaaSmrg      WidthinTiles = (pSAVAGEDRI->width+31)>>5;
1643ab47cfaaSmrg      TileStride = (pSAVAGEDRI->width+31)&(~31);
1644ab47cfaaSmrg
1645ab47cfaaSmrg  }
1646ab47cfaaSmrg
1647ab47cfaaSmrg
1648ab47cfaaSmrg  /* set primary stream stride */
1649ab47cfaaSmrg  {
1650ab47cfaaSmrg      unsigned int value;
1651ab47cfaaSmrg
1652ab47cfaaSmrg      /*value = 0x80000000|(WidthinTiles<<24)|(TileStride*depth/8);*/
1653ab47cfaaSmrg      value = 0x80000000|(WidthinTiles<<24);
1654ab47cfaaSmrg      if(depth == 32)
1655ab47cfaaSmrg          value |= 0x40000000;
1656ab47cfaaSmrg
1657ab47cfaaSmrg      OUTREG(PRI_STREAM_STRIDE, value);
1658ab47cfaaSmrg
1659ab47cfaaSmrg  }
1660ab47cfaaSmrg
1661ab47cfaaSmrg  /* set global bitmap descriptor */
1662ab47cfaaSmrg  {
1663ab47cfaaSmrg      unsigned int value;
1664ab47cfaaSmrg      value = 0x10000000|
1665ab47cfaaSmrg              0x00000009|
1666ab47cfaaSmrg              0x01000000|
1667ab47cfaaSmrg              (depth<<16)  | TileStride;
1668ab47cfaaSmrg
1669ab47cfaaSmrg      OUTREG(0x816C,value);
1670ab47cfaaSmrg
1671ab47cfaaSmrg  }
1672ab47cfaaSmrg
1673ab47cfaaSmrg   OUTREG(0x48C18, INREG(0x48C18) | 0x8);
1674ab47cfaaSmrg
1675ab47cfaaSmrg  return TRUE;
1676ab47cfaaSmrg}
1677ab47cfaaSmrg
1678ab47cfaaSmrgstatic Bool
1679ab47cfaaSmrgSAVAGEDRICloseFullScreen(ScreenPtr pScreen)
1680ab47cfaaSmrg{
1681ab47cfaaSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1682ab47cfaaSmrg  SavagePtr psav = SAVPTR(pScrn);
1683ab47cfaaSmrg  BCI_GET_PTR;
1684ab47cfaaSmrg
1685ab47cfaaSmrg  BCI_SEND(0xC0FF0000);
1686ab47cfaaSmrg  psav->WaitIdleEmpty(psav);
1687ab47cfaaSmrg  OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7);
1688ab47cfaaSmrg  /* set primary stream stride */
1689ab47cfaaSmrg  {
1690ab47cfaaSmrg      /* MM81C0 and 81C4 are used to control primary stream. */
1691ab47cfaaSmrg      OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000);
1692ab47cfaaSmrg      OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000);
1693ab47cfaaSmrg
1694ab47cfaaSmrg      /* FIFO control */
1695ab47cfaaSmrg      OUTREG32(0X81EC,0Xffffffff);
1696ab47cfaaSmrg
1697ab47cfaaSmrg      if (!psav->bTiled) {
1698ab47cfaaSmrg          OUTREG32(PRI_STREAM_STRIDE,
1699ab47cfaaSmrg                   (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
1700ab47cfaaSmrg                   (psav->lDelta & 0x00001fff));
1701ab47cfaaSmrg      }
1702ab47cfaaSmrg      else if (pScrn->bitsPerPixel == 16) {
1703ab47cfaaSmrg          /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
1704ab47cfaaSmrg          OUTREG32(PRI_STREAM_STRIDE,
1705ab47cfaaSmrg                   (((psav->lDelta * 2) << 16) & 0x3FFFE000)
1706ab47cfaaSmrg                   | 0x80000000 | (psav->lDelta & 0x00001fff));
1707ab47cfaaSmrg      }
1708ab47cfaaSmrg      else if (pScrn->bitsPerPixel == 32) {
1709ab47cfaaSmrg          OUTREG32(PRI_STREAM_STRIDE,
1710ab47cfaaSmrg                   (((psav->lDelta * 2) << 16) & 0x3FFFE000)
1711ab47cfaaSmrg                   | 0xC0000000 | (psav->lDelta & 0x00001fff));
1712ab47cfaaSmrg      }
1713ab47cfaaSmrg
1714ab47cfaaSmrg
1715ab47cfaaSmrg  }
1716ab47cfaaSmrg
1717ab47cfaaSmrg  /* set global bitmap descriptor */
1718ab47cfaaSmrg      {
1719ab47cfaaSmrg          OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
1720ab47cfaaSmrg          OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | BCI_ENABLE | S3_LITTLE_ENDIAN | S3_BD64);
1721ab47cfaaSmrg
1722ab47cfaaSmrg      }
1723ab47cfaaSmrg
1724ab47cfaaSmrg  OUTREG(0x48C18, INREG(0x48C18) | 0x8);
1725ab47cfaaSmrg  return TRUE;
1726ab47cfaaSmrg}
1727ab47cfaaSmrg
1728ab47cfaaSmrg#endif
1729