1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.8 2002/12/16 16:18:53 dawes Exp $ */
2 /**************************************************************************
4 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Gareth Hughes <gareth@valinux.com>
32 * Kevin E. Martin <martin@valinux.com>
38 #include "r128_context.h"
39 #include "r128_ioctl.h"
40 #include "r128_tris.h"
50 #include "glxextensions.h"
54 /* Including xf86PciInfo.h introduces a bunch of errors...
56 #define PCI_CHIP_RAGE128LE 0x4C45
57 #define PCI_CHIP_RAGE128LF 0x4C46
58 #define PCI_CHIP_RAGE128PD 0x5044
59 #define PCI_CHIP_RAGE128PF 0x5046
60 #define PCI_CHIP_RAGE128PR 0x5052
61 #define PCI_CHIP_RAGE128RE 0x5245
62 #define PCI_CHIP_RAGE128RF 0x5246
63 #define PCI_CHIP_RAGE128RK 0x524B
64 #define PCI_CHIP_RAGE128RL 0x524C
68 /* Create the device specific screen private data struct.
71 r128CreateScreen( __DRIscreenPrivate
*sPriv
)
73 r128ScreenPtr r128Screen
;
74 R128DRIPtr r128DRIPriv
= (R128DRIPtr
)sPriv
->pDevPriv
;
76 if ( ! driCheckDriDdxDrmVersions( sPriv
, "Rage128", 4, 0, 4, 0, 2, 2 ) )
79 /* Allocate the private area */
80 r128Screen
= (r128ScreenPtr
) CALLOC( sizeof(*r128Screen
) );
81 if ( !r128Screen
) return NULL
;
83 /* This is first since which regions we map depends on whether or
84 * not we are using a PCI card.
86 r128Screen
->IsPCI
= r128DRIPriv
->IsPCI
;
87 r128Screen
->sarea_priv_offset
= r128DRIPriv
->sarea_priv_offset
;
89 if (sPriv
->drmMinor
>= 3) {
93 gp
.param
= R128_PARAM_IRQ_NR
;
94 gp
.value
= &r128Screen
->irq
;
96 ret
= drmCommandWriteRead( sPriv
->fd
, DRM_R128_GETPARAM
,
99 fprintf(stderr
, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret
);
105 r128Screen
->mmio
.handle
= r128DRIPriv
->registerHandle
;
106 r128Screen
->mmio
.size
= r128DRIPriv
->registerSize
;
107 if ( drmMap( sPriv
->fd
,
108 r128Screen
->mmio
.handle
,
109 r128Screen
->mmio
.size
,
110 (drmAddressPtr
)&r128Screen
->mmio
.map
) ) {
115 r128Screen
->buffers
= drmMapBufs( sPriv
->fd
);
116 if ( !r128Screen
->buffers
) {
117 drmUnmap( (drmAddress
)r128Screen
->mmio
.map
, r128Screen
->mmio
.size
);
122 if ( !r128Screen
->IsPCI
) {
123 r128Screen
->agpTextures
.handle
= r128DRIPriv
->agpTexHandle
;
124 r128Screen
->agpTextures
.size
= r128DRIPriv
->agpTexMapSize
;
125 if ( drmMap( sPriv
->fd
,
126 r128Screen
->agpTextures
.handle
,
127 r128Screen
->agpTextures
.size
,
128 (drmAddressPtr
)&r128Screen
->agpTextures
.map
) ) {
129 drmUnmapBufs( r128Screen
->buffers
);
130 drmUnmap( (drmAddress
)r128Screen
->mmio
.map
, r128Screen
->mmio
.size
);
136 switch ( r128DRIPriv
->deviceID
) {
137 case PCI_CHIP_RAGE128RE
:
138 case PCI_CHIP_RAGE128RF
:
139 case PCI_CHIP_RAGE128RK
:
140 case PCI_CHIP_RAGE128RL
:
141 r128Screen
->chipset
= R128_CARD_TYPE_R128
;
143 case PCI_CHIP_RAGE128PD
:
144 case PCI_CHIP_RAGE128PF
:
145 r128Screen
->chipset
= R128_CARD_TYPE_R128_PRO
;
147 case PCI_CHIP_RAGE128LE
:
148 case PCI_CHIP_RAGE128LF
:
149 r128Screen
->chipset
= R128_CARD_TYPE_R128_MOBILITY
;
152 r128Screen
->chipset
= R128_CARD_TYPE_R128
;
156 r128Screen
->cpp
= r128DRIPriv
->bpp
/ 8;
157 r128Screen
->AGPMode
= r128DRIPriv
->AGPMode
;
159 r128Screen
->frontOffset
= r128DRIPriv
->frontOffset
;
160 r128Screen
->frontPitch
= r128DRIPriv
->frontPitch
;
161 r128Screen
->backOffset
= r128DRIPriv
->backOffset
;
162 r128Screen
->backPitch
= r128DRIPriv
->backPitch
;
163 r128Screen
->depthOffset
= r128DRIPriv
->depthOffset
;
164 r128Screen
->depthPitch
= r128DRIPriv
->depthPitch
;
165 r128Screen
->spanOffset
= r128DRIPriv
->spanOffset
;
167 r128Screen
->texOffset
[R128_CARD_HEAP
] = r128DRIPriv
->textureOffset
;
168 r128Screen
->texSize
[R128_CARD_HEAP
] = r128DRIPriv
->textureSize
;
169 r128Screen
->logTexGranularity
[R128_CARD_HEAP
] = r128DRIPriv
->log2TexGran
;
171 if ( r128Screen
->IsPCI
) {
172 r128Screen
->numTexHeaps
= R128_NR_TEX_HEAPS
- 1;
173 r128Screen
->texOffset
[R128_AGP_HEAP
] = 0;
174 r128Screen
->texSize
[R128_AGP_HEAP
] = 0;
175 r128Screen
->logTexGranularity
[R128_AGP_HEAP
] = 0;
177 r128Screen
->numTexHeaps
= R128_NR_TEX_HEAPS
;
178 r128Screen
->texOffset
[R128_AGP_HEAP
] =
179 r128DRIPriv
->agpTexOffset
+ R128_AGP_TEX_OFFSET
;
180 r128Screen
->texSize
[R128_AGP_HEAP
] = r128DRIPriv
->agpTexMapSize
;
181 r128Screen
->logTexGranularity
[R128_AGP_HEAP
] =
182 r128DRIPriv
->log2AGPTexGran
;
185 r128Screen
->driScreen
= sPriv
;
190 /* Destroy the device specific screen private data struct.
193 r128DestroyScreen( __DRIscreenPrivate
*sPriv
)
195 r128ScreenPtr r128Screen
= (r128ScreenPtr
)sPriv
->private;
200 if ( !r128Screen
->IsPCI
) {
201 drmUnmap( (drmAddress
)r128Screen
->agpTextures
.map
,
202 r128Screen
->agpTextures
.size
);
204 drmUnmapBufs( r128Screen
->buffers
);
205 drmUnmap( (drmAddress
)r128Screen
->mmio
.map
, r128Screen
->mmio
.size
);
208 sPriv
->private = NULL
;
212 /* Initialize the fullscreen mode.
215 r128OpenCloseFullScreen( __DRIcontextPrivate
*driContextPriv
)
221 /* Create and initialize the Mesa and driver specific pixmap buffer
225 r128CreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
226 __DRIdrawablePrivate
*driDrawPriv
,
227 const __GLcontextModes
*mesaVis
,
231 return GL_FALSE
; /* not implemented */
234 driDrawPriv
->driverPrivate
= (void *)
235 _mesa_create_framebuffer( mesaVis
,
236 GL_FALSE
, /* software depth buffer? */
237 mesaVis
->stencilBits
> 0,
238 mesaVis
->accumRedBits
> 0,
239 mesaVis
->alphaBits
> 0 );
240 return (driDrawPriv
->driverPrivate
!= NULL
);
246 r128DestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
248 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
252 /* Copy the back color buffer to the front color buffer */
254 r128SwapBuffers(__DRIdrawablePrivate
*dPriv
)
256 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
257 r128ContextPtr rmesa
;
259 rmesa
= (r128ContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
261 if (ctx
->Visual
.doubleBufferMode
) {
262 _mesa_notifySwapBuffers( ctx
); /* flush pending rendering comands */
263 if ( rmesa
->doPageFlip
) {
264 r128PageFlip( dPriv
);
267 r128CopyBuffer( dPriv
);
272 /* XXX this shouldn't be an error but we can't handle it for now */
273 _mesa_problem(NULL
, "%s: drawable has no context!", __FUNCTION__
);
278 /* Initialize the driver specific screen private data.
281 r128InitDriver( __DRIscreenPrivate
*sPriv
)
283 sPriv
->private = (void *) r128CreateScreen( sPriv
);
285 if ( !sPriv
->private ) {
286 r128DestroyScreen( sPriv
);
295 /* This function is called by libGL.so as soon as libGL.so is loaded.
296 * This is where we register new extension functions with the dispatcher.
298 void __driRegisterExtensions( void )
300 PFNGLXENABLEEXTENSIONPROC glx_enable_extension
;
302 if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) {
303 glx_enable_extension
= (PFNGLXENABLEEXTENSIONPROC
)
304 glXGetProcAddress( "__glXEnableExtension" );
306 if ( glx_enable_extension
!= NULL
) {
307 glx_enable_extension( "GLX_SGI_swap_control", GL_FALSE
);
308 glx_enable_extension( "GLX_SGI_video_sync", GL_FALSE
);
309 glx_enable_extension( "GLX_MESA_swap_control", GL_FALSE
);
315 static struct __DriverAPIRec r128API
= {
316 .InitDriver
= r128InitDriver
,
317 .DestroyScreen
= r128DestroyScreen
,
318 .CreateContext
= r128CreateContext
,
319 .DestroyContext
= r128DestroyContext
,
320 .CreateBuffer
= r128CreateBuffer
,
321 .DestroyBuffer
= r128DestroyBuffer
,
322 .SwapBuffers
= r128SwapBuffers
,
323 .MakeCurrent
= r128MakeCurrent
,
324 .UnbindContext
= r128UnbindContext
,
325 .OpenFullScreen
= r128OpenCloseFullScreen
,
326 .CloseFullScreen
= r128OpenCloseFullScreen
,
328 .GetMSC
= driGetMSC32
,
329 .WaitForMSC
= driWaitForMSC32
,
331 .SwapBuffersMSC
= NULL
337 * This is the bootstrap function for the driver.
338 * The __driCreateScreen name is the symbol that libGL.so fetches.
339 * Return: pointer to a __DRIscreenPrivate.
342 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
343 int numConfigs
, __GLXvisualConfig
*config
)
345 __DRIscreenPrivate
*psp
;
346 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &r128API
);
350 void *__driCreateScreen(struct DRIDriverRec
*driver
,
351 struct DRIDriverContextRec
*driverContext
)
353 __DRIscreenPrivate
*psp
;
354 psp
= __driUtilCreateScreen(driver
, driverContext
, &r128API
);