lots of Makefile updates for new build system
[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 /* R128 configuration
54 */
55 #include "xmlpool.h"
56
57 const char __driConfigOptions[] =
58 DRI_CONF_BEGIN
59 DRI_CONF_SECTION_PERFORMANCE
60 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
61 DRI_CONF_SECTION_END
62 DRI_CONF_SECTION_QUALITY
63 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
64 DRI_CONF_SECTION_END
65 #if ENABLE_PERF_BOXES
66 DRI_CONF_SECTION_DEBUG
67 DRI_CONF_PERFORMANCE_BOXES(false)
68 DRI_CONF_SECTION_END
69 #endif
70 DRI_CONF_END;
71 #if ENABLE_PERF_BOXES
72 static const GLuint __driNConfigOptions = 3;
73 #else
74 static const GLuint __driNConfigOptions = 2;
75 #endif
76
77 #if 1
78 /* Including xf86PciInfo.h introduces a bunch of errors...
79 */
80 #define PCI_CHIP_RAGE128LE 0x4C45
81 #define PCI_CHIP_RAGE128LF 0x4C46
82 #define PCI_CHIP_RAGE128PF 0x5046
83 #define PCI_CHIP_RAGE128PR 0x5052
84 #define PCI_CHIP_RAGE128RE 0x5245
85 #define PCI_CHIP_RAGE128RF 0x5246
86 #define PCI_CHIP_RAGE128RK 0x524B
87 #define PCI_CHIP_RAGE128RL 0x524C
88 #endif
89
90
91 /* Create the device specific screen private data struct.
92 */
93 static r128ScreenPtr
94 r128CreateScreen( __DRIscreenPrivate *sPriv )
95 {
96 r128ScreenPtr r128Screen;
97 R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
98
99 if ( ! driCheckDriDdxDrmVersions( sPriv, "Rage128", 4, 0, 4, 0, 2, 2 ) )
100 return NULL;
101
102 /* Allocate the private area */
103 r128Screen = (r128ScreenPtr) CALLOC( sizeof(*r128Screen) );
104 if ( !r128Screen ) return NULL;
105
106 /* parse information in __driConfigOptions */
107 driParseOptionInfo (&r128Screen->optionCache,
108 __driConfigOptions, __driNConfigOptions);
109
110 /* This is first since which regions we map depends on whether or
111 * not we are using a PCI card.
112 */
113 r128Screen->IsPCI = r128DRIPriv->IsPCI;
114 r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset;
115
116 if (sPriv->drmMinor >= 3) {
117 drm_r128_getparam_t gp;
118 int ret;
119
120 gp.param = R128_PARAM_IRQ_NR;
121 gp.value = &r128Screen->irq;
122
123 ret = drmCommandWriteRead( sPriv->fd, DRM_R128_GETPARAM,
124 &gp, sizeof(gp));
125 if (ret) {
126 fprintf(stderr, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret);
127 FREE( r128Screen );
128 return NULL;
129 }
130 }
131
132 r128Screen->mmio.handle = r128DRIPriv->registerHandle;
133 r128Screen->mmio.size = r128DRIPriv->registerSize;
134 if ( drmMap( sPriv->fd,
135 r128Screen->mmio.handle,
136 r128Screen->mmio.size,
137 (drmAddressPtr)&r128Screen->mmio.map ) ) {
138 FREE( r128Screen );
139 return NULL;
140 }
141
142 r128Screen->buffers = drmMapBufs( sPriv->fd );
143 if ( !r128Screen->buffers ) {
144 drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
145 FREE( r128Screen );
146 return NULL;
147 }
148
149 if ( !r128Screen->IsPCI ) {
150 r128Screen->agpTextures.handle = r128DRIPriv->agpTexHandle;
151 r128Screen->agpTextures.size = r128DRIPriv->agpTexMapSize;
152 if ( drmMap( sPriv->fd,
153 r128Screen->agpTextures.handle,
154 r128Screen->agpTextures.size,
155 (drmAddressPtr)&r128Screen->agpTextures.map ) ) {
156 drmUnmapBufs( r128Screen->buffers );
157 drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
158 FREE( r128Screen );
159 return NULL;
160 }
161 }
162
163 switch ( r128DRIPriv->deviceID ) {
164 case PCI_CHIP_RAGE128RE:
165 case PCI_CHIP_RAGE128RF:
166 case PCI_CHIP_RAGE128RK:
167 case PCI_CHIP_RAGE128RL:
168 r128Screen->chipset = R128_CARD_TYPE_R128;
169 break;
170 case PCI_CHIP_RAGE128PF:
171 r128Screen->chipset = R128_CARD_TYPE_R128_PRO;
172 break;
173 case PCI_CHIP_RAGE128LE:
174 case PCI_CHIP_RAGE128LF:
175 r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY;
176 break;
177 default:
178 r128Screen->chipset = R128_CARD_TYPE_R128;
179 break;
180 }
181
182 r128Screen->cpp = r128DRIPriv->bpp / 8;
183 r128Screen->AGPMode = r128DRIPriv->AGPMode;
184
185 r128Screen->frontOffset = r128DRIPriv->frontOffset;
186 r128Screen->frontPitch = r128DRIPriv->frontPitch;
187 r128Screen->backOffset = r128DRIPriv->backOffset;
188 r128Screen->backPitch = r128DRIPriv->backPitch;
189 r128Screen->depthOffset = r128DRIPriv->depthOffset;
190 r128Screen->depthPitch = r128DRIPriv->depthPitch;
191 r128Screen->spanOffset = r128DRIPriv->spanOffset;
192
193 r128Screen->texOffset[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureOffset;
194 r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize;
195 r128Screen->logTexGranularity[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran;
196
197 if ( r128Screen->IsPCI ) {
198 r128Screen->numTexHeaps = R128_NR_TEX_HEAPS - 1;
199 r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0;
200 r128Screen->texSize[R128_AGP_TEX_HEAP] = 0;
201 r128Screen->logTexGranularity[R128_AGP_TEX_HEAP] = 0;
202 } else {
203 r128Screen->numTexHeaps = R128_NR_TEX_HEAPS;
204 r128Screen->texOffset[R128_AGP_TEX_HEAP] =
205 r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET;
206 r128Screen->texSize[R128_AGP_TEX_HEAP] = r128DRIPriv->agpTexMapSize;
207 r128Screen->logTexGranularity[R128_AGP_TEX_HEAP] =
208 r128DRIPriv->log2AGPTexGran;
209 }
210
211 r128Screen->driScreen = sPriv;
212 #ifndef _SOLO
213 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
214 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
215 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
216 void * const psc = sPriv->psc->screenConfigs;
217
218 if ( glx_enable_extension != NULL ) {
219 if ( r128Screen->irq != 0 ) {
220 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
221 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
222 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
223 }
224
225 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
226 }
227 }
228 #endif
229 return r128Screen;
230 }
231
232 /* Destroy the device specific screen private data struct.
233 */
234 static void
235 r128DestroyScreen( __DRIscreenPrivate *sPriv )
236 {
237 r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private;
238
239 if ( !r128Screen )
240 return;
241
242 if ( !r128Screen->IsPCI ) {
243 drmUnmap( (drmAddress)r128Screen->agpTextures.map,
244 r128Screen->agpTextures.size );
245 }
246 drmUnmapBufs( r128Screen->buffers );
247 drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
248
249 /* free all option information */
250 driDestroyOptionInfo (&r128Screen->optionCache);
251
252 FREE( r128Screen );
253 sPriv->private = NULL;
254 }
255
256
257 /* Initialize the fullscreen mode.
258 */
259 static GLboolean
260 r128OpenCloseFullScreen( __DRIcontextPrivate *driContextPriv )
261 {
262 return GL_TRUE;
263 }
264
265
266 /* Create and initialize the Mesa and driver specific pixmap buffer
267 * data.
268 */
269 static GLboolean
270 r128CreateBuffer( __DRIscreenPrivate *driScrnPriv,
271 __DRIdrawablePrivate *driDrawPriv,
272 const __GLcontextModes *mesaVis,
273 GLboolean isPixmap )
274 {
275 if (isPixmap) {
276 return GL_FALSE; /* not implemented */
277 }
278 else {
279 driDrawPriv->driverPrivate = (void *)
280 _mesa_create_framebuffer( mesaVis,
281 GL_FALSE, /* software depth buffer? */
282 mesaVis->stencilBits > 0,
283 mesaVis->accumRedBits > 0,
284 mesaVis->alphaBits > 0 );
285 return (driDrawPriv->driverPrivate != NULL);
286 }
287 }
288
289
290 static void
291 r128DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
292 {
293 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
294 }
295
296
297 /* Copy the back color buffer to the front color buffer */
298 static void
299 r128SwapBuffers(__DRIdrawablePrivate *dPriv)
300 {
301 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
302 r128ContextPtr rmesa;
303 GLcontext *ctx;
304 rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate;
305 ctx = rmesa->glCtx;
306 if (ctx->Visual.doubleBufferMode) {
307 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
308 if ( rmesa->doPageFlip ) {
309 r128PageFlip( dPriv );
310 }
311 else {
312 r128CopyBuffer( dPriv );
313 }
314 }
315 }
316 else {
317 /* XXX this shouldn't be an error but we can't handle it for now */
318 _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
319 }
320 }
321
322
323 /* Initialize the driver specific screen private data.
324 */
325 static GLboolean
326 r128InitDriver( __DRIscreenPrivate *sPriv )
327 {
328 sPriv->private = (void *) r128CreateScreen( sPriv );
329
330 if ( !sPriv->private ) {
331 r128DestroyScreen( sPriv );
332 return GL_FALSE;
333 }
334
335 return GL_TRUE;
336 }
337
338 #ifndef _SOLO
339 /**
340 * This function is called by libGL.so as soon as libGL.so is loaded.
341 * This is where we register new extension functions with the dispatcher.
342 *
343 * \todo This interface has been deprecated, so we should probably remove
344 * this function before the next XFree86 release.
345 */
346 void __driRegisterExtensions( void )
347 {
348 PFNGLXENABLEEXTENSIONPROC glx_enable_extension;
349
350 if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) {
351 glx_enable_extension = (PFNGLXENABLEEXTENSIONPROC)
352 glXGetProcAddress( (const GLubyte *) "__glXEnableExtension" );
353
354 if ( glx_enable_extension != NULL ) {
355 glx_enable_extension( "GLX_SGI_swap_control", GL_FALSE );
356 glx_enable_extension( "GLX_SGI_video_sync", GL_FALSE );
357 glx_enable_extension( "GLX_MESA_swap_control", GL_FALSE );
358 }
359 }
360 }
361 #endif
362
363 static struct __DriverAPIRec r128API = {
364 .InitDriver = r128InitDriver,
365 .DestroyScreen = r128DestroyScreen,
366 .CreateContext = r128CreateContext,
367 .DestroyContext = r128DestroyContext,
368 .CreateBuffer = r128CreateBuffer,
369 .DestroyBuffer = r128DestroyBuffer,
370 .SwapBuffers = r128SwapBuffers,
371 .MakeCurrent = r128MakeCurrent,
372 .UnbindContext = r128UnbindContext,
373 .OpenFullScreen = r128OpenCloseFullScreen,
374 .CloseFullScreen = r128OpenCloseFullScreen,
375 .GetSwapInfo = NULL,
376 .GetMSC = driGetMSC32,
377 .WaitForMSC = driWaitForMSC32,
378 .WaitForSBC = NULL,
379 .SwapBuffersMSC = NULL
380
381 };
382
383
384 /*
385 * This is the bootstrap function for the driver.
386 * The __driCreateScreen name is the symbol that libGL.so fetches.
387 * Return: pointer to a __DRIscreenPrivate.
388 */
389 #ifndef _SOLO
390 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
391 int numConfigs, __GLXvisualConfig *config)
392 {
393 __DRIscreenPrivate *psp;
394 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r128API);
395 return (void *) psp;
396 }
397 #else
398 void *__driCreateScreen(struct DRIDriverRec *driver,
399 struct DRIDriverContextRec *driverContext)
400 {
401 __DRIscreenPrivate *psp;
402 psp = __driUtilCreateScreen(driver, driverContext, &r128API);
403 return (void *) psp;
404 }
405 #endif