Start beginning of pixel shader generator..
[mesa.git] / src / mesa / drivers / dri / r300 / radeon_screen.c
1 /*
2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
3
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /**
31 * \file radeon_screen.c
32 * Screen initialization functions for the R200 driver.
33 *
34 * \author Keith Whitwell <keith@tungstengraphics.com>
35 */
36
37 #include <dlfcn.h>
38
39 #include "glheader.h"
40 #include "imports.h"
41 #include "context.h"
42
43 #define STANDALONE_MMIO
44 #include "radeon_screen.h"
45 #include "r200_context.h"
46 #include "r300_context.h"
47 #include "radeon_ioctl.h"
48 #include "r200_ioctl.h"
49 #include "radeon_macros.h"
50 #include "radeon_reg.h"
51
52 #include "utils.h"
53 #include "vblank.h"
54 #include "GL/internal/dri_interface.h"
55
56 /* R200 configuration
57 */
58 #include "xmlpool.h"
59
60 const char __driR200ConfigOptions[] =
61 DRI_CONF_BEGIN
62 DRI_CONF_SECTION_PERFORMANCE
63 DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
64 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
65 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
66 DRI_CONF_MAX_TEXTURE_UNITS(4, 2, 6)
67 DRI_CONF_SECTION_END
68 DRI_CONF_SECTION_QUALITY
69 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
70 DRI_CONF_DEF_MAX_ANISOTROPY(1.0, "1.0,2.0,4.0,8.0,16.0")
71 DRI_CONF_NO_NEG_LOD_BIAS(false)
72 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
73 DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
74 DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
75 DRI_CONF_SECTION_END
76 DRI_CONF_SECTION_DEBUG
77 DRI_CONF_NO_RAST(false)
78 DRI_CONF_SECTION_END
79 DRI_CONF_SECTION_SOFTWARE
80 DRI_CONF_ARB_VERTEX_PROGRAM(true)
81 DRI_CONF_NV_VERTEX_PROGRAM(false)
82 DRI_CONF_SECTION_END
83 DRI_CONF_END;
84 static const GLuint __driR200NConfigOptions = 13;
85
86 /* TODO: integrate these into xmlpool.h! */
87 #define DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(def,min,max) \
88 DRI_CONF_OPT_BEGIN_V(texture_image_units,int,def, # min ":" # max ) \
89 DRI_CONF_DESC(en,"Number of texture image units") \
90 DRI_CONF_DESC(de,"Anzahl der Textureinheiten") \
91 DRI_CONF_OPT_END
92
93 #define DRI_CONF_MAX_TEXTURE_COORD_UNITS(def,min,max) \
94 DRI_CONF_OPT_BEGIN_V(texture_coord_units,int,def, # min ":" # max ) \
95 DRI_CONF_DESC(en,"Number of texture coordinate units") \
96 DRI_CONF_DESC(de,"Anzahl der Texturkoordinateneinheiten") \
97 DRI_CONF_OPT_END
98
99 #define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \
100 DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
101 DRI_CONF_DESC(en,"Size of command buffer (in KB)") \
102 DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \
103 DRI_CONF_OPT_END
104
105
106 const char __driR300ConfigOptions[] =
107 DRI_CONF_BEGIN
108 DRI_CONF_SECTION_PERFORMANCE
109 DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
110 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
111 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
112 DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(16, 2, 16)
113 DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8)
114 DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
115 DRI_CONF_SECTION_END
116 DRI_CONF_SECTION_QUALITY
117 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
118 DRI_CONF_DEF_MAX_ANISOTROPY(1.0, "1.0,2.0,4.0,8.0,16.0")
119 DRI_CONF_NO_NEG_LOD_BIAS(false)
120 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
121 DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
122 DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
123 DRI_CONF_SECTION_END
124 DRI_CONF_SECTION_DEBUG
125 DRI_CONF_NO_RAST(false)
126 DRI_CONF_SECTION_END
127 DRI_CONF_END;
128 static const GLuint __driR300NConfigOptions = 13;
129
130
131 #ifndef RADEON_DEBUG
132 int RADEON_DEBUG = 0;
133 #endif
134
135 static const struct dri_debug_control debug_control[] = {
136 {"fall", DEBUG_FALLBACKS},
137 {"tex", DEBUG_TEXTURE},
138 {"ioctl", DEBUG_IOCTL},
139 {"prim", DEBUG_PRIMS},
140 {"vert", DEBUG_VERTS},
141 {"state", DEBUG_STATE},
142 {"code", DEBUG_CODEGEN},
143 {"vfmt", DEBUG_VFMT},
144 {"vtxf", DEBUG_VFMT},
145 {"verb", DEBUG_VERBOSE},
146 {"dri", DEBUG_DRI},
147 {"dma", DEBUG_DMA},
148 {"san", DEBUG_SANITY},
149 {"sync", DEBUG_SYNC},
150 {"pix", DEBUG_PIXEL},
151 {"mem", DEBUG_MEMORY},
152 {NULL, 0}
153 };
154
155 #if 1
156 /* Including xf86PciInfo.h introduces a bunch of errors...
157 */
158 #define PCI_CHIP_R200_QD 0x5144 /* why do they have r200 names? */
159 #define PCI_CHIP_R200_QE 0x5145 /* Those are all standard radeons */
160 #define PCI_CHIP_R200_QF 0x5146
161 #define PCI_CHIP_R200_QG 0x5147
162 #define PCI_CHIP_R200_QY 0x5159
163 #define PCI_CHIP_R200_QZ 0x515A
164 #define PCI_CHIP_R200_LW 0x4C57
165 #define PCI_CHIP_R200_LY 0x4C59
166 #define PCI_CHIP_R200_LZ 0x4C5A
167 #define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */
168 #define PCI_CHIP_RV200_QX 0x5158
169 #define PCI_CHIP_RS100_4136 0x4136 /* IGP RS100, RS200, RS250 are not R200 */
170 #define PCI_CHIP_RS200_4137 0x4137
171 #define PCI_CHIP_RS250_4237 0x4237
172 #define PCI_CHIP_RS100_4336 0x4336
173 #define PCI_CHIP_RS200_4337 0x4337
174 #define PCI_CHIP_RS250_4437 0x4437
175 #define PCI_CHIP_RS300_5834 0x5834 /* All RS300's are R200 */
176 #define PCI_CHIP_RS300_5835 0x5835
177 #define PCI_CHIP_RS300_5836 0x5836
178 #define PCI_CHIP_RS300_5837 0x5837
179 #define PCI_CHIP_R200_BB 0x4242 /* r200 (non-derived) start */
180 #define PCI_CHIP_R200_BC 0x4243
181 #define PCI_CHIP_R200_QH 0x5148
182 #define PCI_CHIP_R200_QI 0x5149
183 #define PCI_CHIP_R200_QJ 0x514A
184 #define PCI_CHIP_R200_QK 0x514B
185 #define PCI_CHIP_R200_QL 0x514C
186 #define PCI_CHIP_R200_QM 0x514D
187 #define PCI_CHIP_R200_QN 0x514E
188 #define PCI_CHIP_R200_QO 0x514F /* r200 (non-derived) end */
189 /* are the R200 Qh (0x5168) and following needed too? They are not in xf86PciInfo.h
190 but in the pci database. Maybe just secondary ports or something ? */
191
192 #define PCI_CHIP_R300_AD 0x4144
193 #define PCI_CHIP_R300_AE 0x4145
194 #define PCI_CHIP_R300_AF 0x4146
195 #define PCI_CHIP_R300_AG 0x4147
196 #define PCI_CHIP_RV350_AP 0x4150
197 #define PCI_CHIP_RV350_AS 0x4153
198 #define PCI_CHIP_RV350_NP 0x4E50
199 #define PCI_CHIP_RV350_NT 0x4E54
200 #define PCI_CHIP_R300_ND 0x4E44
201 #define PCI_CHIP_R300_NE 0x4E45
202 #define PCI_CHIP_R300_NF 0x4E46
203 #define PCI_CHIP_R300_NG 0x4E47
204 #define PCI_CHIP_R350_NH 0x4E48
205 #endif
206
207 #ifdef USE_NEW_INTERFACE
208 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
209 #endif /* USE_NEW_INTERFACE */
210
211 static radeonScreenPtr __radeonScreen;
212
213 static int getSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo);
214
215 #ifdef USE_NEW_INTERFACE
216 static __GLcontextModes *radeonFillInModes(unsigned pixel_bits,
217 unsigned depth_bits,
218 unsigned stencil_bits,
219 GLboolean have_back_buffer)
220 {
221 __GLcontextModes *modes;
222 __GLcontextModes *m;
223 unsigned num_modes;
224 unsigned depth_buffer_factor;
225 unsigned back_buffer_factor;
226 GLenum fb_format;
227 GLenum fb_type;
228
229 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
230 * enough to add support. Basically, if a context is created with an
231 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
232 * will never be used.
233 */
234 static const GLenum back_buffer_modes[] = {
235 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
236 };
237
238 uint8_t depth_bits_array[2];
239 uint8_t stencil_bits_array[2];
240
241 depth_bits_array[0] = depth_bits;
242 depth_bits_array[1] = depth_bits;
243
244 /* Just like with the accumulation buffer, always provide some modes
245 * with a stencil buffer. It will be a sw fallback, but some apps won't
246 * care about that.
247 */
248 stencil_bits_array[0] = 0;
249 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
250
251 depth_buffer_factor = ((depth_bits != 0)
252 || (stencil_bits != 0)) ? 2 : 1;
253 back_buffer_factor = (have_back_buffer) ? 2 : 1;
254
255 num_modes = depth_buffer_factor * back_buffer_factor * 4;
256
257 if (pixel_bits == 16) {
258 fb_format = GL_RGB;
259 fb_type = GL_UNSIGNED_SHORT_5_6_5;
260 } else {
261 fb_format = GL_BGRA;
262 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
263 }
264
265 modes = (*create_context_modes) (num_modes, sizeof(__GLcontextModes));
266 m = modes;
267 if (!driFillInModes(&m, fb_format, fb_type,
268 depth_bits_array, stencil_bits_array,
269 depth_buffer_factor, back_buffer_modes,
270 back_buffer_factor, GLX_TRUE_COLOR)) {
271 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
272 __LINE__);
273 return NULL;
274 }
275
276 if (!driFillInModes(&m, fb_format, fb_type,
277 depth_bits_array, stencil_bits_array,
278 depth_buffer_factor, back_buffer_modes,
279 back_buffer_factor, GLX_DIRECT_COLOR)) {
280 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
281 __LINE__);
282 return NULL;
283 }
284
285 /* Mark the visual as slow if there are "fake" stencil bits.
286 */
287 for (m = modes; m != NULL; m = m->next) {
288 if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
289 m->visualRating = GLX_SLOW_CONFIG;
290 }
291 }
292
293 return modes;
294 }
295 #endif /* USE_NEW_INTERFACE */
296
297 /* Create the device specific screen private data struct.
298 */
299 static radeonScreenPtr radeonCreateScreen(__DRIscreenPrivate * sPriv)
300 {
301 radeonScreenPtr screen;
302 RADEONDRIPtr dri_priv = (RADEONDRIPtr) sPriv->pDevPriv;
303 unsigned char *RADEONMMIO;
304
305 /* Allocate the private area */
306 screen = (radeonScreenPtr) CALLOC(sizeof(*screen));
307 if (!screen) {
308 __driUtilMessage
309 ("%s: Could not allocate memory for screen structure",
310 __FUNCTION__);
311 return NULL;
312 }
313
314 #if DO_DEBUG
315 RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
316 #endif
317
318 /* Get family and potential quirks from the PCI device ID.
319 */
320 switch (dri_priv->deviceID) {
321 case PCI_CHIP_R200_QD:
322 case PCI_CHIP_R200_QE:
323 case PCI_CHIP_R200_QF:
324 case PCI_CHIP_R200_QG:
325 case PCI_CHIP_R200_QY:
326 case PCI_CHIP_R200_QZ:
327 case PCI_CHIP_RV200_QW:
328 case PCI_CHIP_RV200_QX:
329 case PCI_CHIP_R200_LW:
330 case PCI_CHIP_R200_LY:
331 case PCI_CHIP_R200_LZ:
332 case PCI_CHIP_RS100_4136:
333 case PCI_CHIP_RS200_4137:
334 case PCI_CHIP_RS250_4237:
335 case PCI_CHIP_RS100_4336:
336 case PCI_CHIP_RS200_4337:
337 case PCI_CHIP_RS250_4437:
338 __driUtilMessage("radeonCreateScreen(): Device isn't an r200!\n");
339 FREE(screen);
340 return NULL;
341
342 case PCI_CHIP_RS300_5834:
343 case PCI_CHIP_RS300_5835:
344 case PCI_CHIP_RS300_5836:
345 case PCI_CHIP_RS300_5837:
346 screen->chipset = RADEON_CHIP_UNREAL_R200;
347 break;
348
349 case PCI_CHIP_R200_BB:
350 case PCI_CHIP_R200_BC:
351 case PCI_CHIP_R200_QH:
352 case PCI_CHIP_R200_QI:
353 case PCI_CHIP_R200_QJ:
354 case PCI_CHIP_R200_QK:
355 case PCI_CHIP_R200_QL:
356 case PCI_CHIP_R200_QM:
357 case PCI_CHIP_R200_QN:
358 case PCI_CHIP_R200_QO:
359 screen->chipset = RADEON_CHIP_REAL_R200 | RADEON_CHIPSET_TCL;
360 break;
361
362 /* TODO: Check all those chips for the exact flags required.
363 */
364 case PCI_CHIP_R300_AD:
365 case PCI_CHIP_R300_AE:
366 case PCI_CHIP_R300_AF:
367 case PCI_CHIP_R300_AG:
368 case PCI_CHIP_RV350_AP:
369 case PCI_CHIP_RV350_AS:
370 case PCI_CHIP_RV350_NP:
371 case PCI_CHIP_RV350_NT:
372 screen->chipset = RADEON_CHIP_RV350;
373 break;
374
375 case PCI_CHIP_R300_ND: /* confirmed -- nh */
376 case PCI_CHIP_R300_NE:
377 case PCI_CHIP_R300_NF:
378 case PCI_CHIP_R300_NG:
379 case PCI_CHIP_R350_NH:
380 screen->chipset = RADEON_CHIP_R300;
381 break;
382
383 default:
384 fprintf(stderr,
385 "Unknown device ID %04X, please report. Assuming plain R300.\n",
386 dri_priv->deviceID);
387 screen->chipset = RADEON_CHIP_R300;
388 }
389
390 /* Parse configuration */
391 if (GET_CHIP(screen) >= RADEON_CHIP_R300) {
392 driParseOptionInfo(&screen->optionCache,
393 __driR300ConfigOptions, __driR300NConfigOptions);
394 } else {
395 driParseOptionInfo(&screen->optionCache,
396 __driR200ConfigOptions, __driR200NConfigOptions);
397 }
398
399 /* This is first since which regions we map depends on whether or
400 * not we are using a PCI card.
401 */
402 screen->IsPCI = dri_priv->IsPCI;
403
404 {
405 int ret;
406 drm_radeon_getparam_t gp;
407
408 gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
409 gp.value = &screen->gart_buffer_offset;
410
411 ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
412 &gp, sizeof(gp));
413 if (ret) {
414 FREE(screen);
415 fprintf(stderr,
416 "drmRadeonGetParam (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n",
417 ret);
418 return NULL;
419 }
420
421 if (sPriv->drmMinor >= 6) {
422 gp.param = RADEON_PARAM_GART_BASE;
423 gp.value = &screen->gart_base;
424
425 ret =
426 drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
427 &gp, sizeof(gp));
428 if (ret) {
429 FREE(screen);
430 fprintf(stderr,
431 "drmR200GetParam (RADEON_PARAM_GART_BASE): %d\n",
432 ret);
433 return NULL;
434 }
435
436 gp.param = RADEON_PARAM_IRQ_NR;
437 gp.value = &screen->irq;
438
439 ret =
440 drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
441 &gp, sizeof(gp));
442 if (ret) {
443 FREE(screen);
444 fprintf(stderr,
445 "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n",
446 ret);
447 return NULL;
448 }
449
450 /* Check if kernel module is new enough to support cube maps */
451 screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
452 /* Check if kernel module is new enough to support blend color and
453 separate blend functions/equations */
454 screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
455
456 }
457 }
458
459 screen->mmio.handle = dri_priv->registerHandle;
460 screen->mmio.size = dri_priv->registerSize;
461 if (drmMap(sPriv->fd,
462 screen->mmio.handle, screen->mmio.size, &screen->mmio.map)) {
463 FREE(screen);
464 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__);
465 return NULL;
466 }
467
468 RADEONMMIO = screen->mmio.map;
469
470 screen->status.handle = dri_priv->statusHandle;
471 screen->status.size = dri_priv->statusSize;
472 if (drmMap(sPriv->fd,
473 screen->status.handle,
474 screen->status.size, &screen->status.map)) {
475 drmUnmap(screen->mmio.map, screen->mmio.size);
476 FREE(screen);
477 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__);
478 return NULL;
479 }
480 screen->scratch = (__volatile__ uint32_t *)
481 ((GLubyte *) screen->status.map + RADEON_SCRATCH_REG_OFFSET);
482
483 screen->buffers = drmMapBufs(sPriv->fd);
484 if (!screen->buffers) {
485 drmUnmap(screen->status.map, screen->status.size);
486 drmUnmap(screen->mmio.map, screen->mmio.size);
487 FREE(screen);
488 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__);
489 return NULL;
490 }
491
492 if (dri_priv->gartTexHandle && dri_priv->gartTexMapSize) {
493
494 screen->gartTextures.handle = dri_priv->gartTexHandle;
495 screen->gartTextures.size = dri_priv->gartTexMapSize;
496 if (drmMap(sPriv->fd,
497 screen->gartTextures.handle,
498 screen->gartTextures.size,
499 (drmAddressPtr) & screen->gartTextures.map)) {
500 drmUnmapBufs(screen->buffers);
501 drmUnmap(screen->status.map, screen->status.size);
502 drmUnmap(screen->mmio.map, screen->mmio.size);
503 FREE(screen);
504 __driUtilMessage
505 ("%s: drmMAP failed for GART texture area\n",
506 __FUNCTION__);
507 return NULL;
508 }
509
510 screen->gart_texture_offset =
511 dri_priv->gartTexOffset +
512 (screen->IsPCI ? INREG(RADEON_AIC_LO_ADDR)
513 : ((INREG(RADEON_MC_AGP_LOCATION) & 0x0ffffU) << 16));
514 }
515
516 screen->cpp = dri_priv->bpp / 8;
517 screen->AGPMode = dri_priv->AGPMode;
518
519 screen->fbLocation = (INREG(RADEON_MC_FB_LOCATION) & 0xffff) << 16;
520
521 if (sPriv->drmMinor >= 10) {
522 drm_radeon_setparam_t sp;
523
524 sp.param = RADEON_SETPARAM_FB_LOCATION;
525 sp.value = screen->fbLocation;
526
527 drmCommandWrite(sPriv->fd, DRM_RADEON_SETPARAM,
528 &sp, sizeof(sp));
529 }
530
531 screen->frontOffset = dri_priv->frontOffset;
532 screen->frontPitch = dri_priv->frontPitch;
533 screen->backOffset = dri_priv->backOffset;
534 screen->backPitch = dri_priv->backPitch;
535 screen->depthOffset = dri_priv->depthOffset;
536 screen->depthPitch = dri_priv->depthPitch;
537
538 screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
539 + screen->fbLocation;
540 screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
541 screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
542 dri_priv->log2TexGran;
543
544 if (!screen->gartTextures.map) {
545 screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
546 screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
547 screen->texSize[RADEON_GART_TEX_HEAP] = 0;
548 screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
549 } else {
550 screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
551 screen->texOffset[RADEON_GART_TEX_HEAP] =
552 screen->gart_texture_offset;
553 screen->texSize[RADEON_GART_TEX_HEAP] =
554 dri_priv->gartTexMapSize;
555 screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
556 dri_priv->log2GARTTexGran;
557 }
558
559 screen->driScreen = sPriv;
560 screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
561
562 if (driCompareGLXAPIVersion(20030813) >= 0) {
563 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
564 (PFNGLXSCRENABLEEXTENSIONPROC)
565 glXGetProcAddress((const GLubyte *)
566 "__glXScrEnableExtension");
567 void *const psc = sPriv->psc->screenConfigs;
568
569 if (glx_enable_extension != NULL) {
570 if (screen->irq != 0) {
571 (*glx_enable_extension) (psc,
572 "GLX_SGI_swap_control");
573 (*glx_enable_extension) (psc,
574 "GLX_SGI_video_sync");
575 (*glx_enable_extension) (psc,
576 "GLX_MESA_swap_control");
577 }
578
579 (*glx_enable_extension) (psc,
580 "GLX_MESA_swap_frame_usage");
581
582 if (driCompareGLXAPIVersion(20030818) >= 0) {
583 sPriv->psc->allocateMemory =
584 (void *)r200AllocateMemoryMESA;
585 sPriv->psc->freeMemory =
586 (void *)r200FreeMemoryMESA;
587 sPriv->psc->memoryOffset =
588 (void *)r200GetMemoryOffsetMESA;
589
590 (*glx_enable_extension) (psc,
591 "GLX_MESA_allocate_memory");
592 }
593
594 if (driCompareGLXAPIVersion(20030915) >= 0) {
595 (*glx_enable_extension) (psc,
596 "GLX_SGIX_fbconfig");
597 (*glx_enable_extension) (psc,
598 "GLX_OML_swap_method");
599 }
600 }
601 }
602 return screen;
603 }
604
605 /* Destroy the device specific screen private data struct.
606 */
607 static void radeonDestroyScreen(__DRIscreenPrivate * sPriv)
608 {
609 radeonScreenPtr screen = (radeonScreenPtr) sPriv->private;
610
611 if (!screen)
612 return;
613
614 if (screen->gartTextures.map) {
615 drmUnmap(screen->gartTextures.map, screen->gartTextures.size);
616 }
617 drmUnmapBufs(screen->buffers);
618 drmUnmap(screen->status.map, screen->status.size);
619 drmUnmap(screen->mmio.map, screen->mmio.size);
620
621 /* free all option information */
622 driDestroyOptionInfo(&screen->optionCache);
623
624 FREE(screen);
625 sPriv->private = NULL;
626 }
627
628 /* Initialize the driver specific screen private data.
629 */
630 static GLboolean radeonInitDriver(__DRIscreenPrivate * sPriv)
631 {
632 __radeonScreen = radeonCreateScreen(sPriv);
633
634 sPriv->private = (void *)__radeonScreen;
635
636 return sPriv->private ? GL_TRUE : GL_FALSE;
637 }
638
639 /**
640 * Create and initialize the Mesa and driver specific pixmap buffer
641 * data.
642 *
643 * \todo This function (and its interface) will need to be updated to support
644 * pbuffers.
645 */
646 static GLboolean
647 radeonCreateBuffer(__DRIscreenPrivate * driScrnPriv,
648 __DRIdrawablePrivate * driDrawPriv,
649 const __GLcontextModes * mesaVis, GLboolean isPixmap)
650 {
651 if (isPixmap) {
652 return GL_FALSE; /* not implemented */
653 } else {
654 const GLboolean swDepth = GL_FALSE;
655 const GLboolean swAlpha = GL_FALSE;
656 const GLboolean swAccum = mesaVis->accumRedBits > 0;
657 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
658 mesaVis->depthBits != 24;
659 driDrawPriv->driverPrivate = (void *)
660 _mesa_create_framebuffer(mesaVis,
661 swDepth,
662 swStencil, swAccum, swAlpha);
663 return (driDrawPriv->driverPrivate != NULL);
664 }
665 }
666
667 static void radeonDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
668 {
669 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->
670 driverPrivate));
671 }
672
673
674 /**
675 * Choose the appropriate CreateContext function based on the chipset.
676 */
677 static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
678 __DRIcontextPrivate * driContextPriv,
679 void *sharedContextPriv)
680 {
681 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
682 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
683 int chip = GET_CHIP(screen);
684
685 if (chip >= RADEON_CHIP_R300)
686 return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
687 else
688 return r200CreateContext(glVisual, driContextPriv, sharedContextPriv);
689 }
690
691
692 /**
693 * Choose the appropriate DestroyContext function based on the chipset.
694 */
695 static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv)
696 {
697 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
698 int chip = GET_CHIP(radeon->radeonScreen);
699
700 if (chip >= RADEON_CHIP_R300)
701 return r300DestroyContext(driContextPriv);
702 else
703 return r200DestroyContext(driContextPriv);
704 }
705
706
707 static const struct __DriverAPIRec radeonAPI = {
708 .InitDriver = radeonInitDriver,
709 .DestroyScreen = radeonDestroyScreen,
710 .CreateContext = radeonCreateContext,
711 .DestroyContext = radeonDestroyContext,
712 .CreateBuffer = radeonCreateBuffer,
713 .DestroyBuffer = radeonDestroyBuffer,
714 .SwapBuffers = radeonSwapBuffers,
715 .MakeCurrent = radeonMakeCurrent,
716 .UnbindContext = radeonUnbindContext,
717 .GetSwapInfo = getSwapInfo,
718 .GetMSC = driGetMSC32,
719 .WaitForMSC = driWaitForMSC32,
720 .WaitForSBC = NULL,
721 .SwapBuffersMSC = NULL
722 };
723
724 /*
725 * This is the bootstrap function for the driver.
726 * The __driCreateScreen name is the symbol that libGL.so fetches.
727 * Return: pointer to a __DRIscreenPrivate.
728 *
729 */
730 #if !defined(DRI_NEW_INTERFACE_ONLY)
731 void *__driCreateScreen(Display * dpy, int scrn, __DRIscreen * psc,
732 int numConfigs, __GLXvisualConfig * config)
733 {
734 __DRIscreenPrivate *psp;
735 psp =
736 __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI);
737 return (void *)psp;
738 }
739 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
740
741 /**
742 * This is the bootstrap function for the driver. libGL supplies all of the
743 * requisite information about the system, and the driver initializes itself.
744 * This routine also fills in the linked list pointed to by \c driver_modes
745 * with the \c __GLcontextModes that the driver can support for windows or
746 * pbuffers.
747 *
748 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
749 * failure.
750 */
751 #ifdef USE_NEW_INTERFACE
752 void *__driCreateNewScreen(__DRInativeDisplay * dpy, int scrn,
753 __DRIscreen * psc, const __GLcontextModes * modes,
754 const __DRIversion * ddx_version,
755 const __DRIversion * dri_version,
756 const __DRIversion * drm_version,
757 const __DRIframebuffer * frame_buffer,
758 drmAddress pSAREA, int fd, int internal_api_version,
759 __GLcontextModes ** driver_modes)
760 {
761 __DRIscreenPrivate *psp;
762 static const __DRIversion ddx_expected = { 4, 0, 0 };
763 static const __DRIversion dri_expected = { 4, 0, 0 };
764 static const __DRIversion drm_expected = { 1, 11, 1 };
765
766 if (!driCheckDriDdxDrmVersions2("R300",
767 dri_version, &dri_expected,
768 ddx_version, &ddx_expected,
769 drm_version, &drm_expected)) {
770 return NULL;
771 }
772
773 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
774 ddx_version, dri_version, drm_version,
775 frame_buffer, pSAREA, fd,
776 internal_api_version, &radeonAPI);
777 if (psp != NULL) {
778 create_context_modes = (PFNGLXCREATECONTEXTMODES)
779 glXGetProcAddress((const GLubyte *)
780 "__glXCreateContextModes");
781 if (create_context_modes != NULL) {
782 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
783 *driver_modes = radeonFillInModes(dri_priv->bpp,
784 (dri_priv->bpp ==
785 16) ? 16 : 24,
786 (dri_priv->bpp ==
787 16) ? 0 : 8,
788 (dri_priv->backOffset !=
789 dri_priv->
790 depthOffset));
791 }
792 }
793
794 return (void *)psp;
795 }
796 #endif /* USE_NEW_INTERFACE */
797
798 /**
799 * Get information about previous buffer swaps.
800 */
801 static int getSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
802 {
803 radeonContextPtr radeon;
804
805 if ((dPriv == NULL) || (dPriv->driContextPriv == NULL)
806 || (dPriv->driContextPriv->driverPrivate == NULL)
807 || (sInfo == NULL)) {
808 return -1;
809 }
810
811 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
812 sInfo->swap_count = radeon->swap_count;
813 sInfo->swap_ust = radeon->swap_ust;
814 sInfo->swap_missed_count = radeon->swap_missed_count;
815
816 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
817 ? driCalculateSwapUsage(dPriv, 0, radeon->swap_missed_ust)
818 : 0.0;
819
820 return 0;
821 }