build fix
[mesa.git] / src / mesa / drivers / dri / r128 / r128_screen.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.9 2003/03/26 20:43:49 tsi Exp $ */
2 /**************************************************************************
3
4 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
5 Cedar Park, Texas.
6 All Rights Reserved.
7
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:
14
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
17 Software.
18
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.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Gareth Hughes <gareth@valinux.com>
32 * Kevin E. Martin <martin@valinux.com>
33 *
34 */
35
36 #include "r128_dri.h"
37
38 #include "r128_context.h"
39 #include "r128_ioctl.h"
40 #include "r128_tris.h"
41 #include "r128_vb.h"
42
43 #include "context.h"
44 #include "imports.h"
45
46 #include "utils.h"
47 #include "vblank.h"
48
49 #ifndef _SOLO
50 #include "glxextensions.h"
51 #endif
52
53 #if 1
54 /* Including xf86PciInfo.h introduces a bunch of errors...
55 */
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
64 #endif
65
66
67 /* Create the device specific screen private data struct.
68 */
69 static r128ScreenPtr
70 r128CreateScreen( __DRIscreenPrivate *sPriv )
71 {
72 r128ScreenPtr r128Screen;
73 R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
74
75 if ( ! driCheckDriDdxDrmVersions( sPriv, "Rage128", 4, 0, 4, 0, 2, 2 ) )
76 return NULL;
77
78 /* Allocate the private area */
79 r128Screen = (r128ScreenPtr) CALLOC( sizeof(*r128Screen) );
80 if ( !r128Screen ) return NULL;
81
82 /* parse information in __driConfigOptions */
83 driParseOptionInfo (&r128Screen->optionCache);
84
85 /* This is first since which regions we map depends on whether or
86 * not we are using a PCI card.
87 */
88 r128Screen->IsPCI = r128DRIPriv->IsPCI;
89 r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset;
90
91 if (sPriv->drmMinor >= 3) {
92 drmR128GetParam gp;
93 int ret;
94
95 gp.param = R128_PARAM_IRQ_NR;
96 gp.value = &r128Screen->irq;
97
98 ret = drmCommandWriteRead( sPriv->fd, DRM_R128_GETPARAM,
99 &gp, sizeof(gp));
100 if (ret) {
101 fprintf(stderr, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret);
102 FREE( r128Screen );
103 return NULL;
104 }
105 }
106
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 ) ) {
113 FREE( r128Screen );
114 return NULL;
115 }
116
117 r128Screen->buffers = drmMapBufs( sPriv->fd );
118 if ( !r128Screen->buffers ) {
119 drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
120 FREE( r128Screen );
121 return NULL;
122 }
123
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 );
133 FREE( r128Screen );
134 return NULL;
135 }
136 }
137
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;
144 break;
145 case PCI_CHIP_RAGE128PF:
146 r128Screen->chipset = R128_CARD_TYPE_R128_PRO;
147 break;
148 case PCI_CHIP_RAGE128LE:
149 case PCI_CHIP_RAGE128LF:
150 r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY;
151 break;
152 default:
153 r128Screen->chipset = R128_CARD_TYPE_R128;
154 break;
155 }
156
157 r128Screen->cpp = r128DRIPriv->bpp / 8;
158 r128Screen->AGPMode = r128DRIPriv->AGPMode;
159
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;
167
168 r128Screen->texOffset[R128_CARD_HEAP] = r128DRIPriv->textureOffset;
169 r128Screen->texSize[R128_CARD_HEAP] = r128DRIPriv->textureSize;
170 r128Screen->logTexGranularity[R128_CARD_HEAP] = r128DRIPriv->log2TexGran;
171
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;
177 } else {
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;
184 }
185
186 r128Screen->driScreen = sPriv;
187 #ifndef _SOLO
188 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
189 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
190 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
191 void * const psc = sPriv->psc->screenConfigs;
192
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" );
198 }
199
200 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
201 }
202 }
203 #endif
204 return r128Screen;
205 }
206
207 /* Destroy the device specific screen private data struct.
208 */
209 static void
210 r128DestroyScreen( __DRIscreenPrivate *sPriv )
211 {
212 r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private;
213
214 if ( !r128Screen )
215 return;
216
217 if ( !r128Screen->IsPCI ) {
218 drmUnmap( (drmAddress)r128Screen->agpTextures.map,
219 r128Screen->agpTextures.size );
220 }
221 drmUnmapBufs( r128Screen->buffers );
222 drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
223
224 /* free all option information */
225 driDestroyOptionInfo (&r128Screen->optionCache);
226
227 FREE( r128Screen );
228 sPriv->private = NULL;
229 }
230
231
232 /* Initialize the fullscreen mode.
233 */
234 static GLboolean
235 r128OpenCloseFullScreen( __DRIcontextPrivate *driContextPriv )
236 {
237 return GL_TRUE;
238 }
239
240
241 /* Create and initialize the Mesa and driver specific pixmap buffer
242 * data.
243 */
244 static GLboolean
245 r128CreateBuffer( __DRIscreenPrivate *driScrnPriv,
246 __DRIdrawablePrivate *driDrawPriv,
247 const __GLcontextModes *mesaVis,
248 GLboolean isPixmap )
249 {
250 if (isPixmap) {
251 return GL_FALSE; /* not implemented */
252 }
253 else {
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);
261 }
262 }
263
264
265 static void
266 r128DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
267 {
268 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
269 }
270
271
272 /* Copy the back color buffer to the front color buffer */
273 static void
274 r128SwapBuffers(__DRIdrawablePrivate *dPriv)
275 {
276 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
277 r128ContextPtr rmesa;
278 GLcontext *ctx;
279 rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate;
280 ctx = rmesa->glCtx;
281 if (ctx->Visual.doubleBufferMode) {
282 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
283 if ( rmesa->doPageFlip ) {
284 r128PageFlip( dPriv );
285 }
286 else {
287 r128CopyBuffer( dPriv );
288 }
289 }
290 }
291 else {
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__);
294 }
295 }
296
297
298 /* Initialize the driver specific screen private data.
299 */
300 static GLboolean
301 r128InitDriver( __DRIscreenPrivate *sPriv )
302 {
303 sPriv->private = (void *) r128CreateScreen( sPriv );
304
305 if ( !sPriv->private ) {
306 r128DestroyScreen( sPriv );
307 return GL_FALSE;
308 }
309
310 return GL_TRUE;
311 }
312
313 #ifndef _SOLO
314 /**
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.
317 *
318 * \todo This interface has been deprecated, so we should probably remove
319 * this function before the next XFree86 release.
320 */
321 void __driRegisterExtensions( void )
322 {
323 PFNGLXENABLEEXTENSIONPROC glx_enable_extension;
324
325 if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) {
326 glx_enable_extension = (PFNGLXENABLEEXTENSIONPROC)
327 glXGetProcAddress( (const GLubyte *) "__glXEnableExtension" );
328
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 );
333 }
334 }
335 }
336 #endif
337
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,
350 .GetSwapInfo = NULL,
351 .GetMSC = driGetMSC32,
352 .WaitForMSC = driWaitForMSC32,
353 .WaitForSBC = NULL,
354 .SwapBuffersMSC = NULL
355
356 };
357
358
359 /*
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.
363 */
364 #ifndef _SOLO
365 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
366 int numConfigs, __GLXvisualConfig *config)
367 {
368 __DRIscreenPrivate *psp;
369 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r128API);
370 return (void *) psp;
371 }
372 #else
373 void *__driCreateScreen(struct DRIDriverRec *driver,
374 struct DRIDriverContextRec *driverContext)
375 {
376 __DRIscreenPrivate *psp;
377 psp = __driUtilCreateScreen(driver, driverContext, &r128API);
378 return (void *) psp;
379 }
380 #endif