1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.9 2003/03/26 20:43:49 tsi 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_RAGE128PF 0x5046
59 #define PCI_CHIP_RAGE128PR 0x5052
60 #define PCI_CHIP_RAGE128RE 0x5245
61 #define PCI_CHIP_RAGE128RF 0x5246
62 #define PCI_CHIP_RAGE128RK 0x524B
63 #define PCI_CHIP_RAGE128RL 0x524C
67 /* Create the device specific screen private data struct.
70 r128CreateScreen( __DRIscreenPrivate
*sPriv
)
72 r128ScreenPtr r128Screen
;
73 R128DRIPtr r128DRIPriv
= (R128DRIPtr
)sPriv
->pDevPriv
;
75 if ( ! driCheckDriDdxDrmVersions( sPriv
, "Rage128", 4, 0, 4, 0, 2, 2 ) )
78 /* Allocate the private area */
79 r128Screen
= (r128ScreenPtr
) CALLOC( sizeof(*r128Screen
) );
80 if ( !r128Screen
) return NULL
;
82 /* parse information in __driConfigOptions */
83 driParseOptionInfo (&r128Screen
->optionCache
);
85 /* This is first since which regions we map depends on whether or
86 * not we are using a PCI card.
88 r128Screen
->IsPCI
= r128DRIPriv
->IsPCI
;
89 r128Screen
->sarea_priv_offset
= r128DRIPriv
->sarea_priv_offset
;
91 if (sPriv
->drmMinor
>= 3) {
95 gp
.param
= R128_PARAM_IRQ_NR
;
96 gp
.value
= &r128Screen
->irq
;
98 ret
= drmCommandWriteRead( sPriv
->fd
, DRM_R128_GETPARAM
,
101 fprintf(stderr
, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret
);
107 r128Screen
->mmio
.handle
= r128DRIPriv
->registerHandle
;
108 r128Screen
->mmio
.size
= r128DRIPriv
->registerSize
;
109 if ( drmMap( sPriv
->fd
,
110 r128Screen
->mmio
.handle
,
111 r128Screen
->mmio
.size
,
112 (drmAddressPtr
)&r128Screen
->mmio
.map
) ) {
117 r128Screen
->buffers
= drmMapBufs( sPriv
->fd
);
118 if ( !r128Screen
->buffers
) {
119 drmUnmap( (drmAddress
)r128Screen
->mmio
.map
, r128Screen
->mmio
.size
);
124 if ( !r128Screen
->IsPCI
) {
125 r128Screen
->agpTextures
.handle
= r128DRIPriv
->agpTexHandle
;
126 r128Screen
->agpTextures
.size
= r128DRIPriv
->agpTexMapSize
;
127 if ( drmMap( sPriv
->fd
,
128 r128Screen
->agpTextures
.handle
,
129 r128Screen
->agpTextures
.size
,
130 (drmAddressPtr
)&r128Screen
->agpTextures
.map
) ) {
131 drmUnmapBufs( r128Screen
->buffers
);
132 drmUnmap( (drmAddress
)r128Screen
->mmio
.map
, r128Screen
->mmio
.size
);
138 switch ( r128DRIPriv
->deviceID
) {
139 case PCI_CHIP_RAGE128RE
:
140 case PCI_CHIP_RAGE128RF
:
141 case PCI_CHIP_RAGE128RK
:
142 case PCI_CHIP_RAGE128RL
:
143 r128Screen
->chipset
= R128_CARD_TYPE_R128
;
145 case PCI_CHIP_RAGE128PF
:
146 r128Screen
->chipset
= R128_CARD_TYPE_R128_PRO
;
148 case PCI_CHIP_RAGE128LE
:
149 case PCI_CHIP_RAGE128LF
:
150 r128Screen
->chipset
= R128_CARD_TYPE_R128_MOBILITY
;
153 r128Screen
->chipset
= R128_CARD_TYPE_R128
;
157 r128Screen
->cpp
= r128DRIPriv
->bpp
/ 8;
158 r128Screen
->AGPMode
= r128DRIPriv
->AGPMode
;
160 r128Screen
->frontOffset
= r128DRIPriv
->frontOffset
;
161 r128Screen
->frontPitch
= r128DRIPriv
->frontPitch
;
162 r128Screen
->backOffset
= r128DRIPriv
->backOffset
;
163 r128Screen
->backPitch
= r128DRIPriv
->backPitch
;
164 r128Screen
->depthOffset
= r128DRIPriv
->depthOffset
;
165 r128Screen
->depthPitch
= r128DRIPriv
->depthPitch
;
166 r128Screen
->spanOffset
= r128DRIPriv
->spanOffset
;
168 r128Screen
->texOffset
[R128_CARD_HEAP
] = r128DRIPriv
->textureOffset
;
169 r128Screen
->texSize
[R128_CARD_HEAP
] = r128DRIPriv
->textureSize
;
170 r128Screen
->logTexGranularity
[R128_CARD_HEAP
] = r128DRIPriv
->log2TexGran
;
172 if ( r128Screen
->IsPCI
) {
173 r128Screen
->numTexHeaps
= R128_NR_TEX_HEAPS
- 1;
174 r128Screen
->texOffset
[R128_AGP_HEAP
] = 0;
175 r128Screen
->texSize
[R128_AGP_HEAP
] = 0;
176 r128Screen
->logTexGranularity
[R128_AGP_HEAP
] = 0;
178 r128Screen
->numTexHeaps
= R128_NR_TEX_HEAPS
;
179 r128Screen
->texOffset
[R128_AGP_HEAP
] =
180 r128DRIPriv
->agpTexOffset
+ R128_AGP_TEX_OFFSET
;
181 r128Screen
->texSize
[R128_AGP_HEAP
] = r128DRIPriv
->agpTexMapSize
;
182 r128Screen
->logTexGranularity
[R128_AGP_HEAP
] =
183 r128DRIPriv
->log2AGPTexGran
;
186 r128Screen
->driScreen
= sPriv
;
188 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
189 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension
=
190 (PFNGLXSCRENABLEEXTENSIONPROC
) glXGetProcAddress( (const GLubyte
*) "__glXScrEnableExtension" );
191 void * const psc
= sPriv
->psc
->screenConfigs
;
193 if ( glx_enable_extension
!= NULL
) {
194 if ( r128Screen
->irq
!= 0 ) {
195 (*glx_enable_extension
)( psc
, "GLX_SGI_swap_control" );
196 (*glx_enable_extension
)( psc
, "GLX_SGI_video_sync" );
197 (*glx_enable_extension
)( psc
, "GLX_MESA_swap_control" );
200 (*glx_enable_extension
)( psc
, "GLX_MESA_swap_frame_usage" );
207 /* Destroy the device specific screen private data struct.
210 r128DestroyScreen( __DRIscreenPrivate
*sPriv
)
212 r128ScreenPtr r128Screen
= (r128ScreenPtr
)sPriv
->private;
217 if ( !r128Screen
->IsPCI
) {
218 drmUnmap( (drmAddress
)r128Screen
->agpTextures
.map
,
219 r128Screen
->agpTextures
.size
);
221 drmUnmapBufs( r128Screen
->buffers
);
222 drmUnmap( (drmAddress
)r128Screen
->mmio
.map
, r128Screen
->mmio
.size
);
224 /* free all option information */
225 driDestroyOptionInfo (&r128Screen
->optionCache
);
228 sPriv
->private = NULL
;
232 /* Initialize the fullscreen mode.
235 r128OpenCloseFullScreen( __DRIcontextPrivate
*driContextPriv
)
241 /* Create and initialize the Mesa and driver specific pixmap buffer
245 r128CreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
246 __DRIdrawablePrivate
*driDrawPriv
,
247 const __GLcontextModes
*mesaVis
,
251 return GL_FALSE
; /* not implemented */
254 driDrawPriv
->driverPrivate
= (void *)
255 _mesa_create_framebuffer( mesaVis
,
256 GL_FALSE
, /* software depth buffer? */
257 mesaVis
->stencilBits
> 0,
258 mesaVis
->accumRedBits
> 0,
259 mesaVis
->alphaBits
> 0 );
260 return (driDrawPriv
->driverPrivate
!= NULL
);
266 r128DestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
268 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
272 /* Copy the back color buffer to the front color buffer */
274 r128SwapBuffers(__DRIdrawablePrivate
*dPriv
)
276 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
277 r128ContextPtr rmesa
;
279 rmesa
= (r128ContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
281 if (ctx
->Visual
.doubleBufferMode
) {
282 _mesa_notifySwapBuffers( ctx
); /* flush pending rendering comands */
283 if ( rmesa
->doPageFlip
) {
284 r128PageFlip( dPriv
);
287 r128CopyBuffer( dPriv
);
292 /* XXX this shouldn't be an error but we can't handle it for now */
293 _mesa_problem(NULL
, "%s: drawable has no context!", __FUNCTION__
);
298 /* Initialize the driver specific screen private data.
301 r128InitDriver( __DRIscreenPrivate
*sPriv
)
303 sPriv
->private = (void *) r128CreateScreen( sPriv
);
305 if ( !sPriv
->private ) {
306 r128DestroyScreen( sPriv
);
315 * This function is called by libGL.so as soon as libGL.so is loaded.
316 * This is where we register new extension functions with the dispatcher.
318 * \todo This interface has been deprecated, so we should probably remove
319 * this function before the next XFree86 release.
321 void __driRegisterExtensions( void )
323 PFNGLXENABLEEXTENSIONPROC glx_enable_extension
;
325 if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) {
326 glx_enable_extension
= (PFNGLXENABLEEXTENSIONPROC
)
327 glXGetProcAddress( (const GLubyte
*) "__glXEnableExtension" );
329 if ( glx_enable_extension
!= NULL
) {
330 glx_enable_extension( "GLX_SGI_swap_control", GL_FALSE
);
331 glx_enable_extension( "GLX_SGI_video_sync", GL_FALSE
);
332 glx_enable_extension( "GLX_MESA_swap_control", GL_FALSE
);
338 static struct __DriverAPIRec r128API
= {
339 .InitDriver
= r128InitDriver
,
340 .DestroyScreen
= r128DestroyScreen
,
341 .CreateContext
= r128CreateContext
,
342 .DestroyContext
= r128DestroyContext
,
343 .CreateBuffer
= r128CreateBuffer
,
344 .DestroyBuffer
= r128DestroyBuffer
,
345 .SwapBuffers
= r128SwapBuffers
,
346 .MakeCurrent
= r128MakeCurrent
,
347 .UnbindContext
= r128UnbindContext
,
348 .OpenFullScreen
= r128OpenCloseFullScreen
,
349 .CloseFullScreen
= r128OpenCloseFullScreen
,
351 .GetMSC
= driGetMSC32
,
352 .WaitForMSC
= driWaitForMSC32
,
354 .SwapBuffersMSC
= NULL
360 * This is the bootstrap function for the driver.
361 * The __driCreateScreen name is the symbol that libGL.so fetches.
362 * Return: pointer to a __DRIscreenPrivate.
365 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
366 int numConfigs
, __GLXvisualConfig
*config
)
368 __DRIscreenPrivate
*psp
;
369 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &r128API
);
373 void *__driCreateScreen(struct DRIDriverRec
*driver
,
374 struct DRIDriverContextRec
*driverContext
)
376 __DRIscreenPrivate
*psp
;
377 psp
= __driUtilCreateScreen(driver
, driverContext
, &r128API
);