Add new void *addr and __DRIdrawablePrivate parameters to
[mesa.git] / src / mesa / drivers / dri / r200 / r200_screen.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_screen.c,v 1.4 2003/05/08 09:25:35 herrb Exp $ */
2 /*
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 /**
32 * \file r200_screen.c
33 * Screen initialization functions for the R200 driver.
34 *
35 * \author Keith Whitwell <keith@tungstengraphics.com>
36 */
37
38 #include <dlfcn.h>
39
40 #include "glheader.h"
41 #include "imports.h"
42 #include "context.h"
43 #include "framebuffer.h"
44 #include "renderbuffer.h"
45
46 #define STANDALONE_MMIO
47 #include "r200_screen.h"
48 #include "r200_context.h"
49 #include "r200_ioctl.h"
50 #include "r200_span.h"
51 #include "radeon_macros.h"
52 #include "radeon_reg.h"
53
54 #include "drirenderbuffer.h"
55 #include "utils.h"
56 #include "vblank.h"
57 #include "GL/internal/dri_interface.h"
58
59 /* R200 configuration
60 */
61 #include "xmlpool.h"
62
63 PUBLIC const char __driConfigOptions[] =
64 DRI_CONF_BEGIN
65 DRI_CONF_SECTION_PERFORMANCE
66 DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
67 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
68 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
69 DRI_CONF_MAX_TEXTURE_UNITS(4,2,6)
70 DRI_CONF_HYPERZ(false)
71 DRI_CONF_SECTION_END
72 DRI_CONF_SECTION_QUALITY
73 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
74 DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
75 DRI_CONF_NO_NEG_LOD_BIAS(false)
76 DRI_CONF_FORCE_S3TC_ENABLE(false)
77 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
78 DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
79 DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
80 DRI_CONF_TEXTURE_LEVEL_HACK(false)
81 DRI_CONF_TEXTURE_BLEND_QUALITY(1.0,"0.0:1.0")
82 DRI_CONF_SECTION_END
83 DRI_CONF_SECTION_DEBUG
84 DRI_CONF_NO_RAST(false)
85 DRI_CONF_SECTION_END
86 DRI_CONF_SECTION_SOFTWARE
87 DRI_CONF_ARB_VERTEX_PROGRAM(true)
88 DRI_CONF_NV_VERTEX_PROGRAM(false)
89 DRI_CONF_SECTION_END
90 DRI_CONF_END;
91 static const GLuint __driNConfigOptions = 17;
92
93 extern const struct dri_extension card_extensions[];
94 extern const struct dri_extension blend_extensions[];
95 extern const struct dri_extension ARB_vp_extension[];
96 extern const struct dri_extension NV_vp_extension[];
97
98 #if 1
99 /* Including xf86PciInfo.h introduces a bunch of errors...
100 */
101 #define PCI_CHIP_R200_QD 0x5144 /* why do they have r200 names? */
102 #define PCI_CHIP_R200_QE 0x5145 /* Those are all standard radeons */
103 #define PCI_CHIP_R200_QF 0x5146
104 #define PCI_CHIP_R200_QG 0x5147
105 #define PCI_CHIP_R200_QY 0x5159
106 #define PCI_CHIP_R200_QZ 0x515A
107 #define PCI_CHIP_R200_LW 0x4C57
108 #define PCI_CHIP_R200_LX 0x4C58
109 #define PCI_CHIP_R200_LY 0x4C59
110 #define PCI_CHIP_R200_LZ 0x4C5A
111 #define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */
112 #define PCI_CHIP_RV200_QX 0x5158
113 #define PCI_CHIP_RS100_4136 0x4136 /* IGP RS100, RS200, RS250 are not R200 */
114 #define PCI_CHIP_RS200_4137 0x4137
115 #define PCI_CHIP_RS250_4237 0x4237
116 #define PCI_CHIP_RS100_4336 0x4336
117 #define PCI_CHIP_RS200_4337 0x4337
118 #define PCI_CHIP_RS250_4437 0x4437
119 #define PCI_CHIP_RS300_5834 0x5834 /* All RS300's are R200 */
120 #define PCI_CHIP_RS300_5835 0x5835
121 #define PCI_CHIP_RS300_5836 0x5836
122 #define PCI_CHIP_RS300_5837 0x5837
123 #define PCI_CHIP_R200_BB 0x4242 /* r200 (non-derived) start */
124 #define PCI_CHIP_R200_BC 0x4243
125 #define PCI_CHIP_R200_QH 0x5148
126 #define PCI_CHIP_R200_QI 0x5149
127 #define PCI_CHIP_R200_QJ 0x514A
128 #define PCI_CHIP_R200_QK 0x514B
129 #define PCI_CHIP_R200_QL 0x514C
130 #define PCI_CHIP_R200_QM 0x514D
131 #define PCI_CHIP_R200_QN 0x514E
132 #define PCI_CHIP_R200_QO 0x514F /* r200 (non-derived) end */
133 /* are the R200 Qh (0x5168) and following needed too? They are not in
134 xf86PciInfo.h but in the pci database. Maybe just secondary ports or
135 something ? Ah well, better be safe than sorry */
136 #define PCI_CHIP_R200_Qh 0x5168
137 #define PCI_CHIP_R200_Qi 0x5169
138 #define PCI_CHIP_R200_Qj 0x516A
139 #define PCI_CHIP_R200_Qk 0x516B
140 #define PCI_CHIP_R200_Ql 0x516C
141
142 #endif
143
144
145 static r200ScreenPtr __r200Screen;
146
147 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
148
149 static __GLcontextModes *
150 r200FillInModes( unsigned pixel_bits, unsigned depth_bits,
151 unsigned stencil_bits, GLboolean have_back_buffer )
152 {
153 __GLcontextModes * modes;
154 __GLcontextModes * m;
155 unsigned num_modes;
156 unsigned depth_buffer_factor;
157 unsigned back_buffer_factor;
158 GLenum fb_format;
159 GLenum fb_type;
160
161 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
162 * enough to add support. Basically, if a context is created with an
163 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
164 * will never be used.
165 */
166 static const GLenum back_buffer_modes[] = {
167 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
168 };
169
170 u_int8_t depth_bits_array[2];
171 u_int8_t stencil_bits_array[2];
172
173
174 depth_bits_array[0] = depth_bits;
175 depth_bits_array[1] = depth_bits;
176
177 /* Just like with the accumulation buffer, always provide some modes
178 * with a stencil buffer. It will be a sw fallback, but some apps won't
179 * care about that.
180 */
181 stencil_bits_array[0] = 0;
182 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
183
184 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
185 back_buffer_factor = (have_back_buffer) ? 2 : 1;
186
187 num_modes = depth_buffer_factor * back_buffer_factor * 4;
188
189 if ( pixel_bits == 16 ) {
190 fb_format = GL_RGB;
191 fb_type = GL_UNSIGNED_SHORT_5_6_5;
192 }
193 else {
194 fb_format = GL_BGRA;
195 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
196 }
197
198 modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) );
199 m = modes;
200 if ( ! driFillInModes( & m, fb_format, fb_type,
201 depth_bits_array, stencil_bits_array, depth_buffer_factor,
202 back_buffer_modes, back_buffer_factor,
203 GLX_TRUE_COLOR ) ) {
204 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
205 __func__, __LINE__ );
206 return NULL;
207 }
208
209 if ( ! driFillInModes( & m, fb_format, fb_type,
210 depth_bits_array, stencil_bits_array, depth_buffer_factor,
211 back_buffer_modes, back_buffer_factor,
212 GLX_DIRECT_COLOR ) ) {
213 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
214 __func__, __LINE__ );
215 return NULL;
216 }
217
218 /* Mark the visual as slow if there are "fake" stencil bits.
219 */
220 for ( m = modes ; m != NULL ; m = m->next ) {
221 if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
222 m->visualRating = GLX_SLOW_CONFIG;
223 }
224 }
225
226 return modes;
227 }
228
229
230 /* Create the device specific screen private data struct.
231 */
232 static r200ScreenPtr
233 r200CreateScreen( __DRIscreenPrivate *sPriv )
234 {
235 r200ScreenPtr screen;
236 RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
237 unsigned char *RADEONMMIO;
238 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
239 (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
240 void * const psc = sPriv->psc->screenConfigs;
241
242 if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) {
243 fprintf(stderr,"\nERROR! sizeof(RADEONDRIRec) does not match passed size from device driver\n");
244 return GL_FALSE;
245 }
246
247 /* Allocate the private area */
248 screen = (r200ScreenPtr) CALLOC( sizeof(*screen) );
249 if ( !screen ) {
250 __driUtilMessage("%s: Could not allocate memory for screen structure",
251 __FUNCTION__);
252 return NULL;
253 }
254
255 screen->chipset = 0;
256 switch ( dri_priv->deviceID ) {
257 case PCI_CHIP_R200_QD:
258 case PCI_CHIP_R200_QE:
259 case PCI_CHIP_R200_QF:
260 case PCI_CHIP_R200_QG:
261 case PCI_CHIP_R200_QY:
262 case PCI_CHIP_R200_QZ:
263 case PCI_CHIP_RV200_QW:
264 case PCI_CHIP_RV200_QX:
265 case PCI_CHIP_R200_LW:
266 case PCI_CHIP_R200_LX:
267 case PCI_CHIP_R200_LY:
268 case PCI_CHIP_R200_LZ:
269 case PCI_CHIP_RS100_4136:
270 case PCI_CHIP_RS200_4137:
271 case PCI_CHIP_RS250_4237:
272 case PCI_CHIP_RS100_4336:
273 case PCI_CHIP_RS200_4337:
274 case PCI_CHIP_RS250_4437:
275 __driUtilMessage("r200CreateScreen(): Device isn't an r200!\n");
276 FREE( screen );
277 return NULL;
278
279 case PCI_CHIP_RS300_5834:
280 case PCI_CHIP_RS300_5835:
281 case PCI_CHIP_RS300_5836:
282 case PCI_CHIP_RS300_5837:
283 break;
284
285 case PCI_CHIP_R200_BB:
286 case PCI_CHIP_R200_BC:
287 case PCI_CHIP_R200_QH:
288 case PCI_CHIP_R200_QI:
289 case PCI_CHIP_R200_QJ:
290 case PCI_CHIP_R200_QK:
291 case PCI_CHIP_R200_QL:
292 case PCI_CHIP_R200_QM:
293 case PCI_CHIP_R200_QN:
294 case PCI_CHIP_R200_QO:
295 case PCI_CHIP_R200_Qh:
296 case PCI_CHIP_R200_Qi:
297 case PCI_CHIP_R200_Qj:
298 case PCI_CHIP_R200_Qk:
299 case PCI_CHIP_R200_Ql:
300 screen->chipset |= R200_CHIPSET_REAL_R200;
301 /* fallthrough */
302 default:
303 screen->chipset |= R200_CHIPSET_TCL;
304 break;
305 }
306
307 /* parse information in __driConfigOptions */
308 driParseOptionInfo (&screen->optionCache,
309 __driConfigOptions, __driNConfigOptions);
310
311 /* This is first since which regions we map depends on whether or
312 * not we are using a PCI card.
313 */
314 screen->IsPCI = dri_priv->IsPCI;
315
316 {
317 int ret;
318 drm_radeon_getparam_t gp;
319
320 gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
321 gp.value = &screen->gart_buffer_offset;
322
323 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
324 &gp, sizeof(gp));
325 if (ret) {
326 FREE( screen );
327 fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
328 return NULL;
329 }
330
331 if (sPriv->drmMinor >= 6) {
332 gp.param = RADEON_PARAM_GART_BASE;
333 gp.value = &screen->gart_base;
334
335 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
336 &gp, sizeof(gp));
337 if (ret) {
338 FREE( screen );
339 fprintf(stderr, "drmR200GetParam (RADEON_PARAM_GART_BASE): %d\n", ret);
340 return NULL;
341 }
342
343
344 gp.param = RADEON_PARAM_IRQ_NR;
345 gp.value = &screen->irq;
346
347 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
348 &gp, sizeof(gp));
349 if (ret) {
350 FREE( screen );
351 fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret);
352 return NULL;
353 }
354
355 /* Check if kernel module is new enough to support cube maps */
356 screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
357 /* Check if kernel module is new enough to support blend color and
358 separate blend functions/equations */
359 screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
360
361 screen->drmSupportsTriPerf = (sPriv->drmMinor >= 16);
362 }
363 /* Check if ddx has set up a surface reg to cover depth buffer */
364 screen->depthHasSurface = (sPriv->ddxMajor > 4);
365 }
366
367 screen->mmio.handle = dri_priv->registerHandle;
368 screen->mmio.size = dri_priv->registerSize;
369 if ( drmMap( sPriv->fd,
370 screen->mmio.handle,
371 screen->mmio.size,
372 &screen->mmio.map ) ) {
373 FREE( screen );
374 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
375 return NULL;
376 }
377
378 RADEONMMIO = screen->mmio.map;
379
380 screen->status.handle = dri_priv->statusHandle;
381 screen->status.size = dri_priv->statusSize;
382 if ( drmMap( sPriv->fd,
383 screen->status.handle,
384 screen->status.size,
385 &screen->status.map ) ) {
386 drmUnmap( screen->mmio.map, screen->mmio.size );
387 FREE( screen );
388 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
389 return NULL;
390 }
391 screen->scratch = (__volatile__ u_int32_t *)
392 ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
393
394 screen->buffers = drmMapBufs( sPriv->fd );
395 if ( !screen->buffers ) {
396 drmUnmap( screen->status.map, screen->status.size );
397 drmUnmap( screen->mmio.map, screen->mmio.size );
398 FREE( screen );
399 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
400 return NULL;
401 }
402
403 RADEONMMIO = screen->mmio.map;
404
405 if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
406
407 screen->gartTextures.handle = dri_priv->gartTexHandle;
408 screen->gartTextures.size = dri_priv->gartTexMapSize;
409 if ( drmMap( sPriv->fd,
410 screen->gartTextures.handle,
411 screen->gartTextures.size,
412 (drmAddressPtr)&screen->gartTextures.map ) ) {
413 drmUnmapBufs( screen->buffers );
414 drmUnmap( screen->status.map, screen->status.size );
415 drmUnmap( screen->mmio.map, screen->mmio.size );
416 FREE( screen );
417 __driUtilMessage("%s: drmMAP failed for GART texture area\n", __FUNCTION__);
418 return NULL;
419 }
420
421 screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
422 ? INREG( RADEON_AIC_LO_ADDR )
423 : ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
424 }
425
426 screen->cpp = dri_priv->bpp / 8;
427 screen->AGPMode = dri_priv->AGPMode;
428
429 screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
430
431 if ( sPriv->drmMinor >= 10 ) {
432 drm_radeon_setparam_t sp;
433
434 sp.param = RADEON_SETPARAM_FB_LOCATION;
435 sp.value = screen->fbLocation;
436
437 drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
438 &sp, sizeof( sp ) );
439 }
440
441 screen->frontOffset = dri_priv->frontOffset;
442 screen->frontPitch = dri_priv->frontPitch;
443 screen->backOffset = dri_priv->backOffset;
444 screen->backPitch = dri_priv->backPitch;
445 screen->depthOffset = dri_priv->depthOffset;
446 screen->depthPitch = dri_priv->depthPitch;
447
448 screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
449 + screen->fbLocation;
450 screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
451 screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
452 dri_priv->log2TexGran;
453
454 if ( !screen->gartTextures.map ) {
455 screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
456 screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
457 screen->texSize[RADEON_GART_TEX_HEAP] = 0;
458 screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
459 } else {
460 screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
461 screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
462 screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
463 screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
464 dri_priv->log2GARTTexGran;
465 }
466
467 screen->driScreen = sPriv;
468 screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
469
470 if ( glx_enable_extension != NULL ) {
471 if ( screen->irq != 0 ) {
472 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
473 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
474 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
475 }
476
477 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
478 (*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
479 }
480
481 sPriv->psc->allocateMemory = (void *) r200AllocateMemoryMESA;
482 sPriv->psc->freeMemory = (void *) r200FreeMemoryMESA;
483 sPriv->psc->memoryOffset = (void *) r200GetMemoryOffsetMESA;
484
485 return screen;
486 }
487
488 /* Destroy the device specific screen private data struct.
489 */
490 static void
491 r200DestroyScreen( __DRIscreenPrivate *sPriv )
492 {
493 r200ScreenPtr screen = (r200ScreenPtr)sPriv->private;
494
495 if (!screen)
496 return;
497
498 if ( screen->gartTextures.map ) {
499 drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
500 }
501 drmUnmapBufs( screen->buffers );
502 drmUnmap( screen->status.map, screen->status.size );
503 drmUnmap( screen->mmio.map, screen->mmio.size );
504
505 /* free all option information */
506 driDestroyOptionInfo (&screen->optionCache);
507
508 FREE( screen );
509 sPriv->private = NULL;
510 }
511
512
513 /* Initialize the driver specific screen private data.
514 */
515 static GLboolean
516 r200InitDriver( __DRIscreenPrivate *sPriv )
517 {
518 __r200Screen = r200CreateScreen( sPriv );
519
520 sPriv->private = (void *) __r200Screen;
521
522 return sPriv->private ? GL_TRUE : GL_FALSE;
523 }
524
525
526 /**
527 * Create and initialize the Mesa and driver specific pixmap buffer
528 * data. This is called to setup rendering to a particular window.
529 *
530 * \todo This function (and its interface) will need to be updated to support
531 * pbuffers.
532 */
533 static GLboolean
534 r200CreateBuffer( __DRIscreenPrivate *driScrnPriv,
535 __DRIdrawablePrivate *driDrawPriv,
536 const __GLcontextModes *mesaVis,
537 GLboolean isPixmap )
538 {
539 r200ScreenPtr screen = (r200ScreenPtr) driScrnPriv->private;
540
541 if (isPixmap) {
542 return GL_FALSE; /* not implemented */
543 }
544 else {
545 const GLboolean swDepth = GL_FALSE;
546 const GLboolean swAlpha = GL_FALSE;
547 const GLboolean swAccum = mesaVis->accumRedBits > 0;
548 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
549 mesaVis->depthBits != 24;
550 struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
551
552 /* front color renderbuffer */
553 {
554 driRenderbuffer *frontRb
555 = driNewRenderbuffer(GL_RGBA,
556 driScrnPriv->pFB + screen->frontOffset,
557 screen->cpp,
558 screen->frontOffset, screen->frontPitch,
559 driDrawPriv);
560 r200SetSpanFunctions(frontRb, mesaVis);
561 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
562 }
563
564 /* back color renderbuffer */
565 if (mesaVis->doubleBufferMode) {
566 driRenderbuffer *backRb
567 = driNewRenderbuffer(GL_RGBA,
568 driScrnPriv->pFB + screen->backOffset,
569 screen->cpp,
570 screen->backOffset, screen->backPitch,
571 driDrawPriv);
572 r200SetSpanFunctions(backRb, mesaVis);
573 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
574 }
575
576 /* depth renderbuffer */
577 if (mesaVis->depthBits == 16) {
578 driRenderbuffer *depthRb
579 = driNewRenderbuffer(GL_DEPTH_COMPONENT16,
580 driScrnPriv->pFB + screen->depthOffset,
581 screen->cpp,
582 screen->depthOffset, screen->depthPitch,
583 driDrawPriv);
584 r200SetSpanFunctions(depthRb, mesaVis);
585 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
586 depthRb->depthHasSurface = screen->depthHasSurface;
587 }
588 else if (mesaVis->depthBits == 24) {
589 driRenderbuffer *depthRb
590 = driNewRenderbuffer(GL_DEPTH_COMPONENT24,
591 driScrnPriv->pFB + screen->depthOffset,
592 screen->cpp,
593 screen->depthOffset, screen->depthPitch,
594 driDrawPriv);
595 r200SetSpanFunctions(depthRb, mesaVis);
596 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
597 depthRb->depthHasSurface = screen->depthHasSurface;
598 }
599
600 /* stencil renderbuffer */
601 if (mesaVis->stencilBits > 0 && !swStencil) {
602 driRenderbuffer *stencilRb
603 = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
604 driScrnPriv->pFB + screen->depthOffset,
605 screen->cpp,
606 screen->depthOffset, screen->depthPitch,
607 driDrawPriv);
608 r200SetSpanFunctions(stencilRb, mesaVis);
609 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
610 stencilRb->depthHasSurface = screen->depthHasSurface;
611 }
612
613 _mesa_add_soft_renderbuffers(fb,
614 GL_FALSE, /* color */
615 swDepth,
616 swStencil,
617 swAccum,
618 swAlpha,
619 GL_FALSE /* aux */);
620 driDrawPriv->driverPrivate = (void *) fb;
621
622 return (driDrawPriv->driverPrivate != NULL);
623 }
624 }
625
626
627 static void
628 r200DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
629 {
630 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
631 }
632
633
634
635
636 static const struct __DriverAPIRec r200API = {
637 .InitDriver = r200InitDriver,
638 .DestroyScreen = r200DestroyScreen,
639 .CreateContext = r200CreateContext,
640 .DestroyContext = r200DestroyContext,
641 .CreateBuffer = r200CreateBuffer,
642 .DestroyBuffer = r200DestroyBuffer,
643 .SwapBuffers = r200SwapBuffers,
644 .MakeCurrent = r200MakeCurrent,
645 .UnbindContext = r200UnbindContext,
646 .GetSwapInfo = getSwapInfo,
647 .GetMSC = driGetMSC32,
648 .WaitForMSC = driWaitForMSC32,
649 .WaitForSBC = NULL,
650 .SwapBuffersMSC = NULL
651 };
652
653
654 /**
655 * This is the bootstrap function for the driver. libGL supplies all of the
656 * requisite information about the system, and the driver initializes itself.
657 * This routine also fills in the linked list pointed to by \c driver_modes
658 * with the \c __GLcontextModes that the driver can support for windows or
659 * pbuffers.
660 *
661 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
662 * failure.
663 */
664 PUBLIC
665 void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
666 const __GLcontextModes * modes,
667 const __DRIversion * ddx_version,
668 const __DRIversion * dri_version,
669 const __DRIversion * drm_version,
670 const __DRIframebuffer * frame_buffer,
671 drmAddress pSAREA, int fd,
672 int internal_api_version,
673 const __DRIinterfaceMethods * interface,
674 __GLcontextModes ** driver_modes )
675
676 {
677 __DRIscreenPrivate *psp;
678 static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
679 static const __DRIversion dri_expected = { 4, 0, 0 };
680 static const __DRIversion drm_expected = { 1, 5, 0 };
681
682 dri_interface = interface;
683
684 if ( ! driCheckDriDdxDrmVersions3( "R200",
685 dri_version, & dri_expected,
686 ddx_version, & ddx_expected,
687 drm_version, & drm_expected ) ) {
688 return NULL;
689 }
690
691 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
692 ddx_version, dri_version, drm_version,
693 frame_buffer, pSAREA, fd,
694 internal_api_version, &r200API);
695 if ( psp != NULL ) {
696 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
697 *driver_modes = r200FillInModes( dri_priv->bpp,
698 (dri_priv->bpp == 16) ? 16 : 24,
699 (dri_priv->bpp == 16) ? 0 : 8,
700 (dri_priv->backOffset != dri_priv->depthOffset) );
701
702 /* Calling driInitExtensions here, with a NULL context pointer, does not actually
703 * enable the extensions. It just makes sure that all the dispatch offsets for all
704 * the extensions that *might* be enables are known. This is needed because the
705 * dispatch offsets need to be known when _mesa_context_create is called, but we can't
706 * enable the extensions until we have a context pointer.
707 *
708 * Hello chicken. Hello egg. How are you two today?
709 */
710 driInitExtensions( NULL, card_extensions, GL_FALSE );
711 driInitExtensions( NULL, blend_extensions, GL_FALSE );
712 driInitSingleExtension( NULL, ARB_vp_extension );
713 driInitSingleExtension( NULL, NV_vp_extension );
714 }
715
716 return (void *) psp;
717 }
718
719
720 /**
721 * Get information about previous buffer swaps.
722 */
723 static int
724 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
725 {
726 r200ContextPtr rmesa;
727
728 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
729 || (dPriv->driContextPriv->driverPrivate == NULL)
730 || (sInfo == NULL) ) {
731 return -1;
732 }
733
734 rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
735 sInfo->swap_count = rmesa->swap_count;
736 sInfo->swap_ust = rmesa->swap_ust;
737 sInfo->swap_missed_count = rmesa->swap_missed_count;
738
739 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
740 ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
741 : 0.0;
742
743 return 0;
744 }