mesa: added "main/" prefix to includes, remove some -I paths from Makefile.template
[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_span.h"
41 #include "r128_tris.h"
42
43 #include "main/context.h"
44 #include "main/imports.h"
45 #include "main/framebuffer.h"
46 #include "main/renderbuffer.h"
47
48 #include "utils.h"
49 #include "vblank.h"
50
51 #include "GL/internal/dri_interface.h"
52
53 /* R128 configuration
54 */
55 #include "xmlpool.h"
56
57 PUBLIC 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 DRI_CONF_SECTION_DEBUG
66 DRI_CONF_NO_RAST(false)
67 #if ENABLE_PERF_BOXES
68 DRI_CONF_PERFORMANCE_BOXES(false)
69 #endif
70 DRI_CONF_SECTION_END
71 DRI_CONF_END;
72 #if ENABLE_PERF_BOXES
73 static const GLuint __driNConfigOptions = 4;
74 #else
75 static const GLuint __driNConfigOptions = 3;
76 #endif
77
78 extern const struct dri_extension card_extensions[];
79
80 #if 1
81 /* Including xf86PciInfo.h introduces a bunch of errors...
82 */
83 #define PCI_CHIP_RAGE128LE 0x4C45
84 #define PCI_CHIP_RAGE128LF 0x4C46
85 #define PCI_CHIP_RAGE128PF 0x5046
86 #define PCI_CHIP_RAGE128PR 0x5052
87 #define PCI_CHIP_RAGE128RE 0x5245
88 #define PCI_CHIP_RAGE128RF 0x5246
89 #define PCI_CHIP_RAGE128RK 0x524B
90 #define PCI_CHIP_RAGE128RL 0x524C
91 #endif
92
93
94 /* Create the device specific screen private data struct.
95 */
96 static r128ScreenPtr
97 r128CreateScreen( __DRIscreenPrivate *sPriv )
98 {
99 r128ScreenPtr r128Screen;
100 R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
101 int i;
102
103 if (sPriv->devPrivSize != sizeof(R128DRIRec)) {
104 fprintf(stderr,"\nERROR! sizeof(R128DRIRec) does not match passed size from device driver\n");
105 return GL_FALSE;
106 }
107
108 /* Allocate the private area */
109 r128Screen = (r128ScreenPtr) CALLOC( sizeof(*r128Screen) );
110 if ( !r128Screen ) return NULL;
111
112 /* parse information in __driConfigOptions */
113 driParseOptionInfo (&r128Screen->optionCache,
114 __driConfigOptions, __driNConfigOptions);
115
116 /* This is first since which regions we map depends on whether or
117 * not we are using a PCI card.
118 */
119 r128Screen->IsPCI = r128DRIPriv->IsPCI;
120 r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset;
121
122 if (sPriv->drm_version.minor >= 3) {
123 drm_r128_getparam_t gp;
124 int ret;
125
126 gp.param = R128_PARAM_IRQ_NR;
127 gp.value = &r128Screen->irq;
128
129 ret = drmCommandWriteRead( sPriv->fd, DRM_R128_GETPARAM,
130 &gp, sizeof(gp));
131 if (ret) {
132 fprintf(stderr, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret);
133 FREE( r128Screen );
134 return NULL;
135 }
136 }
137
138 r128Screen->mmio.handle = r128DRIPriv->registerHandle;
139 r128Screen->mmio.size = r128DRIPriv->registerSize;
140 if ( drmMap( sPriv->fd,
141 r128Screen->mmio.handle,
142 r128Screen->mmio.size,
143 (drmAddressPtr)&r128Screen->mmio.map ) ) {
144 FREE( r128Screen );
145 return NULL;
146 }
147
148 r128Screen->buffers = drmMapBufs( sPriv->fd );
149 if ( !r128Screen->buffers ) {
150 drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
151 FREE( r128Screen );
152 return NULL;
153 }
154
155 if ( !r128Screen->IsPCI ) {
156 r128Screen->agpTextures.handle = r128DRIPriv->agpTexHandle;
157 r128Screen->agpTextures.size = r128DRIPriv->agpTexMapSize;
158 if ( drmMap( sPriv->fd,
159 r128Screen->agpTextures.handle,
160 r128Screen->agpTextures.size,
161 (drmAddressPtr)&r128Screen->agpTextures.map ) ) {
162 drmUnmapBufs( r128Screen->buffers );
163 drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
164 FREE( r128Screen );
165 return NULL;
166 }
167 }
168
169 switch ( r128DRIPriv->deviceID ) {
170 case PCI_CHIP_RAGE128RE:
171 case PCI_CHIP_RAGE128RF:
172 case PCI_CHIP_RAGE128RK:
173 case PCI_CHIP_RAGE128RL:
174 r128Screen->chipset = R128_CARD_TYPE_R128;
175 break;
176 case PCI_CHIP_RAGE128PF:
177 r128Screen->chipset = R128_CARD_TYPE_R128_PRO;
178 break;
179 case PCI_CHIP_RAGE128LE:
180 case PCI_CHIP_RAGE128LF:
181 r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY;
182 break;
183 default:
184 r128Screen->chipset = R128_CARD_TYPE_R128;
185 break;
186 }
187
188 r128Screen->cpp = r128DRIPriv->bpp / 8;
189 r128Screen->AGPMode = r128DRIPriv->AGPMode;
190
191 r128Screen->frontOffset = r128DRIPriv->frontOffset;
192 r128Screen->frontPitch = r128DRIPriv->frontPitch;
193 r128Screen->backOffset = r128DRIPriv->backOffset;
194 r128Screen->backPitch = r128DRIPriv->backPitch;
195 r128Screen->depthOffset = r128DRIPriv->depthOffset;
196 r128Screen->depthPitch = r128DRIPriv->depthPitch;
197 r128Screen->spanOffset = r128DRIPriv->spanOffset;
198
199 if ( r128DRIPriv->textureSize == 0 ) {
200 r128Screen->texOffset[R128_LOCAL_TEX_HEAP] =
201 r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET;
202 r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->agpTexMapSize;
203 r128Screen->logTexGranularity[R128_LOCAL_TEX_HEAP] =
204 r128DRIPriv->log2AGPTexGran;
205 } else {
206 r128Screen->texOffset[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureOffset;
207 r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize;
208 r128Screen->logTexGranularity[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran;
209 }
210
211 if ( !r128Screen->agpTextures.map || r128DRIPriv->textureSize == 0 ) {
212 r128Screen->numTexHeaps = R128_NR_TEX_HEAPS - 1;
213 r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0;
214 r128Screen->texSize[R128_AGP_TEX_HEAP] = 0;
215 r128Screen->logTexGranularity[R128_AGP_TEX_HEAP] = 0;
216 } else {
217 r128Screen->numTexHeaps = R128_NR_TEX_HEAPS;
218 r128Screen->texOffset[R128_AGP_TEX_HEAP] =
219 r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET;
220 r128Screen->texSize[R128_AGP_TEX_HEAP] = r128DRIPriv->agpTexMapSize;
221 r128Screen->logTexGranularity[R128_AGP_TEX_HEAP] =
222 r128DRIPriv->log2AGPTexGran;
223 }
224
225 r128Screen->driScreen = sPriv;
226
227 i = 0;
228 r128Screen->extensions[i++] = &driFrameTrackingExtension.base;
229 if ( r128Screen->irq != 0 ) {
230 r128Screen->extensions[i++] = &driSwapControlExtension.base;
231 r128Screen->extensions[i++] = &driMediaStreamCounterExtension.base;
232 }
233 r128Screen->extensions[i++] = NULL;
234 sPriv->extensions = r128Screen->extensions;
235
236 return r128Screen;
237 }
238
239 /* Destroy the device specific screen private data struct.
240 */
241 static void
242 r128DestroyScreen( __DRIscreenPrivate *sPriv )
243 {
244 r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private;
245
246 if ( !r128Screen )
247 return;
248
249 if ( !r128Screen->IsPCI ) {
250 drmUnmap( (drmAddress)r128Screen->agpTextures.map,
251 r128Screen->agpTextures.size );
252 }
253 drmUnmapBufs( r128Screen->buffers );
254 drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
255
256 /* free all option information */
257 driDestroyOptionInfo (&r128Screen->optionCache);
258
259 FREE( r128Screen );
260 sPriv->private = NULL;
261 }
262
263
264 /* Create and initialize the Mesa and driver specific pixmap buffer
265 * data.
266 */
267 static GLboolean
268 r128CreateBuffer( __DRIscreenPrivate *driScrnPriv,
269 __DRIdrawablePrivate *driDrawPriv,
270 const __GLcontextModes *mesaVis,
271 GLboolean isPixmap )
272 {
273 r128ScreenPtr screen = (r128ScreenPtr) driScrnPriv->private;
274
275 if (isPixmap) {
276 return GL_FALSE; /* not implemented */
277 }
278 else {
279 const GLboolean swDepth = GL_FALSE;
280 const GLboolean swAlpha = GL_FALSE;
281 const GLboolean swAccum = mesaVis->accumRedBits > 0;
282 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
283 mesaVis->depthBits != 24;
284 struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
285
286 {
287 driRenderbuffer *frontRb
288 = driNewRenderbuffer(GL_RGBA,
289 NULL,
290 screen->cpp,
291 screen->frontOffset, screen->frontPitch,
292 driDrawPriv);
293 r128SetSpanFunctions(frontRb, mesaVis);
294 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
295 }
296
297 if (mesaVis->doubleBufferMode) {
298 driRenderbuffer *backRb
299 = driNewRenderbuffer(GL_RGBA,
300 NULL,
301 screen->cpp,
302 screen->backOffset, screen->backPitch,
303 driDrawPriv);
304 r128SetSpanFunctions(backRb, mesaVis);
305 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
306 }
307
308 if (mesaVis->depthBits == 16) {
309 driRenderbuffer *depthRb
310 = driNewRenderbuffer(GL_DEPTH_COMPONENT16,
311 NULL,
312 screen->cpp,
313 screen->depthOffset, screen->depthPitch,
314 driDrawPriv);
315 r128SetSpanFunctions(depthRb, mesaVis);
316 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
317 }
318 else if (mesaVis->depthBits == 24) {
319 driRenderbuffer *depthRb
320 = driNewRenderbuffer(GL_DEPTH_COMPONENT24,
321 NULL,
322 screen->cpp,
323 screen->depthOffset, screen->depthPitch,
324 driDrawPriv);
325 r128SetSpanFunctions(depthRb, mesaVis);
326 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
327 }
328
329 if (mesaVis->stencilBits > 0 && !swStencil) {
330 driRenderbuffer *stencilRb
331 = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
332 NULL,
333 screen->cpp,
334 screen->depthOffset, screen->depthPitch,
335 driDrawPriv);
336 r128SetSpanFunctions(stencilRb, mesaVis);
337 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
338 }
339
340 _mesa_add_soft_renderbuffers(fb,
341 GL_FALSE, /* color */
342 swDepth,
343 swStencil,
344 swAccum,
345 swAlpha,
346 GL_FALSE /* aux */);
347 driDrawPriv->driverPrivate = (void *) fb;
348
349 return (driDrawPriv->driverPrivate != NULL);
350 }
351 }
352
353
354 static void
355 r128DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
356 {
357 _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
358 }
359
360
361 /* Copy the back color buffer to the front color buffer */
362 static void
363 r128SwapBuffers(__DRIdrawablePrivate *dPriv)
364 {
365 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
366 r128ContextPtr rmesa;
367 GLcontext *ctx;
368 rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate;
369 ctx = rmesa->glCtx;
370 if (ctx->Visual.doubleBufferMode) {
371 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
372 if ( rmesa->doPageFlip ) {
373 r128PageFlip( dPriv );
374 }
375 else {
376 r128CopyBuffer( dPriv );
377 }
378 }
379 }
380 else {
381 /* XXX this shouldn't be an error but we can't handle it for now */
382 _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
383 }
384 }
385
386
387 /* Initialize the driver specific screen private data.
388 */
389 static GLboolean
390 r128InitDriver( __DRIscreenPrivate *sPriv )
391 {
392 sPriv->private = (void *) r128CreateScreen( sPriv );
393
394 if ( !sPriv->private ) {
395 r128DestroyScreen( sPriv );
396 return GL_FALSE;
397 }
398
399 return GL_TRUE;
400 }
401
402 static const __DRIconfig **
403 r128FillInModes( __DRIscreenPrivate *psp,
404 unsigned pixel_bits, unsigned depth_bits,
405 unsigned stencil_bits, GLboolean have_back_buffer )
406 {
407 __DRIconfig **configs;
408 __GLcontextModes * m;
409 unsigned depth_buffer_factor;
410 unsigned back_buffer_factor;
411 GLenum fb_format;
412 GLenum fb_type;
413 int i;
414
415 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
416 * enough to add support. Basically, if a context is created with an
417 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
418 * will never be used.
419 */
420 static const GLenum back_buffer_modes[] = {
421 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
422 };
423
424 u_int8_t depth_bits_array[2];
425 u_int8_t stencil_bits_array[2];
426
427
428 depth_bits_array[0] = depth_bits;
429 depth_bits_array[1] = depth_bits;
430
431 /* Just like with the accumulation buffer, always provide some modes
432 * with a stencil buffer. It will be a sw fallback, but some apps won't
433 * care about that.
434 */
435 stencil_bits_array[0] = 0;
436 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
437
438 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
439 back_buffer_factor = (have_back_buffer) ? 2 : 1;
440
441 if ( pixel_bits == 16 ) {
442 fb_format = GL_RGB;
443 fb_type = GL_UNSIGNED_SHORT_5_6_5;
444 }
445 else {
446 fb_format = GL_BGR;
447 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
448 }
449
450 configs = driCreateConfigs(fb_format, fb_type,
451 depth_bits_array, stencil_bits_array,
452 depth_buffer_factor, back_buffer_modes,
453 back_buffer_factor);
454 if (configs == NULL) {
455 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
456 __LINE__);
457 return NULL;
458 }
459
460 /* Mark the visual as slow if there are "fake" stencil bits.
461 */
462 for (i = 0; configs[i]; i++) {
463 m = &configs[i]->modes;
464 if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
465 m->visualRating = GLX_SLOW_CONFIG;
466 }
467 }
468
469 return (const __DRIconfig **) configs;
470 }
471
472
473 /**
474 * This is the driver specific part of the createNewScreen entry point.
475 *
476 * \todo maybe fold this into intelInitDriver
477 *
478 * \return the __GLcontextModes supported by this driver
479 */
480 static const __DRIconfig **
481 r128InitScreen(__DRIscreenPrivate *psp)
482 {
483 static const __DRIversion ddx_expected = { 4, 0, 0 };
484 static const __DRIversion dri_expected = { 4, 0, 0 };
485 static const __DRIversion drm_expected = { 2, 2, 0 };
486 R128DRIPtr dri_priv = (R128DRIPtr) psp->pDevPriv;
487
488 if ( ! driCheckDriDdxDrmVersions2( "Rage128",
489 &psp->dri_version, & dri_expected,
490 &psp->ddx_version, & ddx_expected,
491 &psp->drm_version, & drm_expected ) )
492 return NULL;
493
494 /* Calling driInitExtensions here, with a NULL context pointer,
495 * does not actually enable the extensions. It just makes sure
496 * that all the dispatch offsets for all the extensions that
497 * *might* be enables are known. This is needed because the
498 * dispatch offsets need to be known when _mesa_context_create is
499 * called, but we can't enable the extensions until we have a
500 * context pointer.
501 *
502 * Hello chicken. Hello egg. How are you two today?
503 */
504 driInitExtensions( NULL, card_extensions, GL_FALSE );
505
506 if (!r128InitDriver(psp))
507 return NULL;
508
509 return r128FillInModes( psp,
510 dri_priv->bpp,
511 (dri_priv->bpp == 16) ? 16 : 24,
512 (dri_priv->bpp == 16) ? 0 : 8,
513 (dri_priv->backOffset != dri_priv->depthOffset) );
514 }
515
516 const struct __DriverAPIRec driDriverAPI = {
517 .InitScreen = r128InitScreen,
518 .DestroyScreen = r128DestroyScreen,
519 .CreateContext = r128CreateContext,
520 .DestroyContext = r128DestroyContext,
521 .CreateBuffer = r128CreateBuffer,
522 .DestroyBuffer = r128DestroyBuffer,
523 .SwapBuffers = r128SwapBuffers,
524 .MakeCurrent = r128MakeCurrent,
525 .UnbindContext = r128UnbindContext,
526 .GetSwapInfo = NULL,
527 .GetDrawableMSC = driDrawableGetMSC32,
528 .WaitForMSC = driWaitForMSC32,
529 .WaitForSBC = NULL,
530 .SwapBuffersMSC = NULL
531 };