Added 0x4e51 - Saphire 9600 256MB
[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 {"allmsg", ~DEBUG_SYNC}, /* avoid the term "sync" because the parser uses strstr */
153 {NULL, 0}
154 };
155
156 #if 1
157 /* Including xf86PciInfo.h introduces a bunch of errors...
158 */
159 #define PCI_CHIP_R200_QD 0x5144 /* why do they have r200 names? */
160 #define PCI_CHIP_R200_QE 0x5145 /* Those are all standard radeons */
161 #define PCI_CHIP_R200_QF 0x5146
162 #define PCI_CHIP_R200_QG 0x5147
163 #define PCI_CHIP_R200_QY 0x5159
164 #define PCI_CHIP_R200_QZ 0x515A
165 #define PCI_CHIP_R200_LW 0x4C57
166 #define PCI_CHIP_R200_LY 0x4C59
167 #define PCI_CHIP_R200_LZ 0x4C5A
168 #define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */
169 #define PCI_CHIP_RV200_QX 0x5158
170 #define PCI_CHIP_RS100_4136 0x4136 /* IGP RS100, RS200, RS250 are not R200 */
171 #define PCI_CHIP_RS200_4137 0x4137
172 #define PCI_CHIP_RS250_4237 0x4237
173 #define PCI_CHIP_RS100_4336 0x4336
174 #define PCI_CHIP_RS200_4337 0x4337
175 #define PCI_CHIP_RS250_4437 0x4437
176 #define PCI_CHIP_RS300_5834 0x5834 /* All RS300's are R200 */
177 #define PCI_CHIP_RS300_5835 0x5835
178 #define PCI_CHIP_RS300_5836 0x5836
179 #define PCI_CHIP_RS300_5837 0x5837
180 #define PCI_CHIP_R200_BB 0x4242 /* r200 (non-derived) start */
181 #define PCI_CHIP_R200_BC 0x4243
182 #define PCI_CHIP_R200_QH 0x5148
183 #define PCI_CHIP_R200_QI 0x5149
184 #define PCI_CHIP_R200_QJ 0x514A
185 #define PCI_CHIP_R200_QK 0x514B
186 #define PCI_CHIP_R200_QL 0x514C
187 #define PCI_CHIP_R200_QM 0x514D
188 #define PCI_CHIP_R200_QN 0x514E
189 #define PCI_CHIP_R200_QO 0x514F /* r200 (non-derived) end */
190 /* are the R200 Qh (0x5168) and following needed too? They are not in xf86PciInfo.h
191 but in the pci database. Maybe just secondary ports or something ? */
192
193 #define PCI_CHIP_R300_AD 0x4144
194 #define PCI_CHIP_R300_AE 0x4145
195 #define PCI_CHIP_R300_AF 0x4146
196 #define PCI_CHIP_R300_AG 0x4147
197 #define PCI_CHIP_RV350_AP 0x4150
198 #define PCI_CHIP_RV350_AR 0x4152
199 #define PCI_CHIP_RV350_AS 0x4153
200 #define PCI_CHIP_RV350_NP 0x4E50
201 #define PCI_CHIP_RV350_NQ 0x4E51 /* Saphire 9600 256MB card */
202 #define PCI_CHIP_RV350_NT 0x4E54
203 #define PCI_CHIP_RV350_NQ_2 0x4E71 /* Saphire 9600 256MB card - Second Head */
204 #define PCI_CHIP_R300_ND 0x4E44
205 #define PCI_CHIP_R300_NE 0x4E45
206 #define PCI_CHIP_R300_NF 0x4E46
207 #define PCI_CHIP_R300_NG 0x4E47
208 #define PCI_CHIP_R350_NH 0x4E48
209 #define PCI_CHIP_R420_JK 0x4a4b
210 #endif
211
212 #ifdef USE_NEW_INTERFACE
213 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
214 #endif /* USE_NEW_INTERFACE */
215
216 static radeonScreenPtr __radeonScreen;
217
218 static int getSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo);
219
220 #ifdef USE_NEW_INTERFACE
221 static __GLcontextModes *radeonFillInModes(unsigned pixel_bits,
222 unsigned depth_bits,
223 unsigned stencil_bits,
224 GLboolean have_back_buffer)
225 {
226 __GLcontextModes *modes;
227 __GLcontextModes *m;
228 unsigned num_modes;
229 unsigned depth_buffer_factor;
230 unsigned back_buffer_factor;
231 GLenum fb_format;
232 GLenum fb_type;
233
234 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
235 * enough to add support. Basically, if a context is created with an
236 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
237 * will never be used.
238 */
239 static const GLenum back_buffer_modes[] = {
240 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
241 };
242
243 uint8_t depth_bits_array[2];
244 uint8_t stencil_bits_array[2];
245
246 depth_bits_array[0] = depth_bits;
247 depth_bits_array[1] = depth_bits;
248
249 /* Just like with the accumulation buffer, always provide some modes
250 * with a stencil buffer. It will be a sw fallback, but some apps won't
251 * care about that.
252 */
253 stencil_bits_array[0] = 0;
254 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
255
256 depth_buffer_factor = ((depth_bits != 0)
257 || (stencil_bits != 0)) ? 2 : 1;
258 back_buffer_factor = (have_back_buffer) ? 2 : 1;
259
260 num_modes = depth_buffer_factor * back_buffer_factor * 4;
261
262 if (pixel_bits == 16) {
263 fb_format = GL_RGB;
264 fb_type = GL_UNSIGNED_SHORT_5_6_5;
265 } else {
266 fb_format = GL_BGRA;
267 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
268 }
269
270 modes = (*create_context_modes) (num_modes, sizeof(__GLcontextModes));
271 m = modes;
272 if (!driFillInModes(&m, fb_format, fb_type,
273 depth_bits_array, stencil_bits_array,
274 depth_buffer_factor, back_buffer_modes,
275 back_buffer_factor, GLX_TRUE_COLOR)) {
276 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
277 __LINE__);
278 return NULL;
279 }
280
281 if (!driFillInModes(&m, fb_format, fb_type,
282 depth_bits_array, stencil_bits_array,
283 depth_buffer_factor, back_buffer_modes,
284 back_buffer_factor, GLX_DIRECT_COLOR)) {
285 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
286 __LINE__);
287 return NULL;
288 }
289
290 /* Mark the visual as slow if there are "fake" stencil bits.
291 */
292 for (m = modes; m != NULL; m = m->next) {
293 if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
294 m->visualRating = GLX_SLOW_CONFIG;
295 }
296 }
297
298 return modes;
299 }
300 #endif /* USE_NEW_INTERFACE */
301
302 /* Create the device specific screen private data struct.
303 */
304 static radeonScreenPtr radeonCreateScreen(__DRIscreenPrivate * sPriv)
305 {
306 radeonScreenPtr screen;
307 RADEONDRIPtr dri_priv = (RADEONDRIPtr) sPriv->pDevPriv;
308 unsigned char *RADEONMMIO;
309
310 /* Allocate the private area */
311 screen = (radeonScreenPtr) CALLOC(sizeof(*screen));
312 if (!screen) {
313 __driUtilMessage
314 ("%s: Could not allocate memory for screen structure",
315 __FUNCTION__);
316 return NULL;
317 }
318
319 #if DO_DEBUG
320 RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
321 #endif
322
323 /* Get family and potential quirks from the PCI device ID.
324 */
325 switch (dri_priv->deviceID) {
326 case PCI_CHIP_R200_QD:
327 case PCI_CHIP_R200_QE:
328 case PCI_CHIP_R200_QF:
329 case PCI_CHIP_R200_QG:
330 case PCI_CHIP_R200_QY:
331 case PCI_CHIP_R200_QZ:
332 case PCI_CHIP_RV200_QW:
333 case PCI_CHIP_RV200_QX:
334 case PCI_CHIP_R200_LW:
335 case PCI_CHIP_R200_LY:
336 case PCI_CHIP_R200_LZ:
337 case PCI_CHIP_RS100_4136:
338 case PCI_CHIP_RS200_4137:
339 case PCI_CHIP_RS250_4237:
340 case PCI_CHIP_RS100_4336:
341 case PCI_CHIP_RS200_4337:
342 case PCI_CHIP_RS250_4437:
343 __driUtilMessage("radeonCreateScreen(): Device isn't an r200!\n");
344 FREE(screen);
345 return NULL;
346
347 case PCI_CHIP_RS300_5834:
348 case PCI_CHIP_RS300_5835:
349 case PCI_CHIP_RS300_5836:
350 case PCI_CHIP_RS300_5837:
351 screen->chipset = RADEON_CHIP_UNREAL_R200;
352 break;
353
354 case PCI_CHIP_R200_BB:
355 case PCI_CHIP_R200_BC:
356 case PCI_CHIP_R200_QH:
357 case PCI_CHIP_R200_QI:
358 case PCI_CHIP_R200_QJ:
359 case PCI_CHIP_R200_QK:
360 case PCI_CHIP_R200_QL:
361 case PCI_CHIP_R200_QM:
362 case PCI_CHIP_R200_QN:
363 case PCI_CHIP_R200_QO:
364 screen->chipset = RADEON_CHIP_REAL_R200 | RADEON_CHIPSET_TCL;
365 break;
366
367 /* TODO: Check all those chips for the exact flags required.
368 */
369 case PCI_CHIP_R300_AD:
370 case PCI_CHIP_R300_AE:
371 case PCI_CHIP_R300_AF:
372 case PCI_CHIP_R300_AG:
373 case PCI_CHIP_RV350_AP:
374 case PCI_CHIP_RV350_AR:
375 case PCI_CHIP_RV350_AS:
376 case PCI_CHIP_RV350_NP:
377 case PCI_CHIP_RV350_NT:
378 case PCI_CHIP_RV350_NQ:
379 /* case PCI_CHIP_RV350_NQ: -- Should we have the second head in here too? */
380 screen->chipset = RADEON_CHIP_RV350;
381 break;
382
383 case PCI_CHIP_R300_ND: /* confirmed -- nh */
384 case PCI_CHIP_R300_NE:
385 case PCI_CHIP_R300_NF:
386 case PCI_CHIP_R300_NG:
387 case PCI_CHIP_R350_NH:
388 screen->chipset = RADEON_CHIP_R300;
389 break;
390
391 case PCI_CHIP_R420_JK:
392 screen->chipset = RADEON_CHIP_R420;
393 break;
394
395 default:
396 fprintf(stderr,
397 "Unknown device ID %04X, please report. Assuming plain R300.\n",
398 dri_priv->deviceID);
399 screen->chipset = RADEON_CHIP_R300;
400 }
401
402 /* Parse configuration */
403 if (GET_CHIP(screen) >= RADEON_CHIP_R300) {
404 driParseOptionInfo(&screen->optionCache,
405 __driR300ConfigOptions, __driR300NConfigOptions);
406 } else {
407 driParseOptionInfo(&screen->optionCache,
408 __driR200ConfigOptions, __driR200NConfigOptions);
409 }
410
411 /* This is first since which regions we map depends on whether or
412 * not we are using a PCI card.
413 */
414 screen->IsPCI = dri_priv->IsPCI;
415
416 {
417 int ret;
418 drm_radeon_getparam_t gp;
419
420 gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
421 gp.value = &screen->gart_buffer_offset;
422
423 ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
424 &gp, sizeof(gp));
425 if (ret) {
426 FREE(screen);
427 fprintf(stderr,
428 "drmRadeonGetParam (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n",
429 ret);
430 return NULL;
431 }
432
433 if (sPriv->drmMinor >= 6) {
434 gp.param = RADEON_PARAM_GART_BASE;
435 gp.value = &screen->gart_base;
436
437 ret =
438 drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
439 &gp, sizeof(gp));
440 if (ret) {
441 FREE(screen);
442 fprintf(stderr,
443 "drmR200GetParam (RADEON_PARAM_GART_BASE): %d\n",
444 ret);
445 return NULL;
446 }
447
448 gp.param = RADEON_PARAM_IRQ_NR;
449 gp.value = &screen->irq;
450
451 ret =
452 drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
453 &gp, sizeof(gp));
454 if (ret) {
455 FREE(screen);
456 fprintf(stderr,
457 "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n",
458 ret);
459 return NULL;
460 }
461
462 /* Check if kernel module is new enough to support cube maps */
463 screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
464 /* Check if kernel module is new enough to support blend color and
465 separate blend functions/equations */
466 screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
467
468 }
469 }
470
471 screen->mmio.handle = dri_priv->registerHandle;
472 screen->mmio.size = dri_priv->registerSize;
473 if (drmMap(sPriv->fd,
474 screen->mmio.handle, screen->mmio.size, &screen->mmio.map)) {
475 FREE(screen);
476 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__);
477 return NULL;
478 }
479
480 RADEONMMIO = screen->mmio.map;
481
482 screen->status.handle = dri_priv->statusHandle;
483 screen->status.size = dri_priv->statusSize;
484 if (drmMap(sPriv->fd,
485 screen->status.handle,
486 screen->status.size, &screen->status.map)) {
487 drmUnmap(screen->mmio.map, screen->mmio.size);
488 FREE(screen);
489 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__);
490 return NULL;
491 }
492 screen->scratch = (__volatile__ uint32_t *)
493 ((GLubyte *) screen->status.map + RADEON_SCRATCH_REG_OFFSET);
494
495 screen->buffers = drmMapBufs(sPriv->fd);
496 if (!screen->buffers) {
497 drmUnmap(screen->status.map, screen->status.size);
498 drmUnmap(screen->mmio.map, screen->mmio.size);
499 FREE(screen);
500 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__);
501 return NULL;
502 }
503
504 if (dri_priv->gartTexHandle && dri_priv->gartTexMapSize) {
505
506 screen->gartTextures.handle = dri_priv->gartTexHandle;
507 screen->gartTextures.size = dri_priv->gartTexMapSize;
508 if (drmMap(sPriv->fd,
509 screen->gartTextures.handle,
510 screen->gartTextures.size,
511 (drmAddressPtr) & screen->gartTextures.map)) {
512 drmUnmapBufs(screen->buffers);
513 drmUnmap(screen->status.map, screen->status.size);
514 drmUnmap(screen->mmio.map, screen->mmio.size);
515 FREE(screen);
516 __driUtilMessage
517 ("%s: drmMAP failed for GART texture area\n",
518 __FUNCTION__);
519 return NULL;
520 }
521
522 screen->gart_texture_offset =
523 dri_priv->gartTexOffset +
524 (screen->IsPCI ? INREG(RADEON_AIC_LO_ADDR)
525 : ((INREG(RADEON_MC_AGP_LOCATION) & 0x0ffffU) << 16));
526 }
527
528 screen->cpp = dri_priv->bpp / 8;
529 screen->AGPMode = dri_priv->AGPMode;
530
531 screen->fbLocation = (INREG(RADEON_MC_FB_LOCATION) & 0xffff) << 16;
532
533 if (sPriv->drmMinor >= 10) {
534 drm_radeon_setparam_t sp;
535
536 sp.param = RADEON_SETPARAM_FB_LOCATION;
537 sp.value = screen->fbLocation;
538
539 drmCommandWrite(sPriv->fd, DRM_RADEON_SETPARAM,
540 &sp, sizeof(sp));
541 }
542
543 screen->frontOffset = dri_priv->frontOffset;
544 screen->frontPitch = dri_priv->frontPitch;
545 screen->backOffset = dri_priv->backOffset;
546 screen->backPitch = dri_priv->backPitch;
547 screen->depthOffset = dri_priv->depthOffset;
548 screen->depthPitch = dri_priv->depthPitch;
549
550 screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
551 + screen->fbLocation;
552 screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
553 screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
554 dri_priv->log2TexGran;
555
556 if (!screen->gartTextures.map) {
557 screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
558 screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
559 screen->texSize[RADEON_GART_TEX_HEAP] = 0;
560 screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
561 } else {
562 screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
563 screen->texOffset[RADEON_GART_TEX_HEAP] =
564 screen->gart_texture_offset;
565 screen->texSize[RADEON_GART_TEX_HEAP] =
566 dri_priv->gartTexMapSize;
567 screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
568 dri_priv->log2GARTTexGran;
569 }
570
571 screen->driScreen = sPriv;
572 screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
573
574 if (driCompareGLXAPIVersion(20030813) >= 0) {
575 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
576 (PFNGLXSCRENABLEEXTENSIONPROC)
577 glXGetProcAddress((const GLubyte *)
578 "__glXScrEnableExtension");
579 void *const psc = sPriv->psc->screenConfigs;
580
581 if (glx_enable_extension != NULL) {
582 if (screen->irq != 0) {
583 (*glx_enable_extension) (psc,
584 "GLX_SGI_swap_control");
585 (*glx_enable_extension) (psc,
586 "GLX_SGI_video_sync");
587 (*glx_enable_extension) (psc,
588 "GLX_MESA_swap_control");
589 }
590
591 (*glx_enable_extension) (psc,
592 "GLX_MESA_swap_frame_usage");
593
594 if (driCompareGLXAPIVersion(20030818) >= 0) {
595 sPriv->psc->allocateMemory =
596 (void *)r200AllocateMemoryMESA;
597 sPriv->psc->freeMemory =
598 (void *)r200FreeMemoryMESA;
599 sPriv->psc->memoryOffset =
600 (void *)r200GetMemoryOffsetMESA;
601
602 (*glx_enable_extension) (psc,
603 "GLX_MESA_allocate_memory");
604 }
605
606 if (driCompareGLXAPIVersion(20030915) >= 0) {
607 (*glx_enable_extension) (psc,
608 "GLX_SGIX_fbconfig");
609 (*glx_enable_extension) (psc,
610 "GLX_OML_swap_method");
611 }
612 }
613 }
614 return screen;
615 }
616
617 /* Destroy the device specific screen private data struct.
618 */
619 static void radeonDestroyScreen(__DRIscreenPrivate * sPriv)
620 {
621 radeonScreenPtr screen = (radeonScreenPtr) sPriv->private;
622
623 if (!screen)
624 return;
625
626 if (screen->gartTextures.map) {
627 drmUnmap(screen->gartTextures.map, screen->gartTextures.size);
628 }
629 drmUnmapBufs(screen->buffers);
630 drmUnmap(screen->status.map, screen->status.size);
631 drmUnmap(screen->mmio.map, screen->mmio.size);
632
633 /* free all option information */
634 driDestroyOptionInfo(&screen->optionCache);
635
636 FREE(screen);
637 sPriv->private = NULL;
638 }
639
640 /* Initialize the driver specific screen private data.
641 */
642 static GLboolean radeonInitDriver(__DRIscreenPrivate * sPriv)
643 {
644 __radeonScreen = radeonCreateScreen(sPriv);
645
646 sPriv->private = (void *)__radeonScreen;
647
648 return sPriv->private ? GL_TRUE : GL_FALSE;
649 }
650
651 /**
652 * Create and initialize the Mesa and driver specific pixmap buffer
653 * data.
654 *
655 * \todo This function (and its interface) will need to be updated to support
656 * pbuffers.
657 */
658 static GLboolean
659 radeonCreateBuffer(__DRIscreenPrivate * driScrnPriv,
660 __DRIdrawablePrivate * driDrawPriv,
661 const __GLcontextModes * mesaVis, GLboolean isPixmap)
662 {
663 if (isPixmap) {
664 return GL_FALSE; /* not implemented */
665 } else {
666 const GLboolean swDepth = GL_FALSE;
667 const GLboolean swAlpha = GL_FALSE;
668 const GLboolean swAccum = mesaVis->accumRedBits > 0;
669 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
670 mesaVis->depthBits != 24;
671 driDrawPriv->driverPrivate = (void *)
672 _mesa_create_framebuffer(mesaVis,
673 swDepth,
674 swStencil, swAccum, swAlpha);
675 return (driDrawPriv->driverPrivate != NULL);
676 }
677 }
678
679 static void radeonDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
680 {
681 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->
682 driverPrivate));
683 }
684
685
686 /**
687 * Choose the appropriate CreateContext function based on the chipset.
688 */
689 static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
690 __DRIcontextPrivate * driContextPriv,
691 void *sharedContextPriv)
692 {
693 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
694 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
695 int chip = GET_CHIP(screen);
696
697 if (chip >= RADEON_CHIP_R300)
698 return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
699 else
700 return r200CreateContext(glVisual, driContextPriv, sharedContextPriv);
701 }
702
703
704 /**
705 * Choose the appropriate DestroyContext function based on the chipset.
706 */
707 static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv)
708 {
709 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
710 int chip = GET_CHIP(radeon->radeonScreen);
711
712 if (chip >= RADEON_CHIP_R300)
713 return r300DestroyContext(driContextPriv);
714 else
715 return r200DestroyContext(driContextPriv);
716 }
717
718
719 static const struct __DriverAPIRec radeonAPI = {
720 .InitDriver = radeonInitDriver,
721 .DestroyScreen = radeonDestroyScreen,
722 .CreateContext = radeonCreateContext,
723 .DestroyContext = radeonDestroyContext,
724 .CreateBuffer = radeonCreateBuffer,
725 .DestroyBuffer = radeonDestroyBuffer,
726 .SwapBuffers = radeonSwapBuffers,
727 .MakeCurrent = radeonMakeCurrent,
728 .UnbindContext = radeonUnbindContext,
729 .GetSwapInfo = getSwapInfo,
730 .GetMSC = driGetMSC32,
731 .WaitForMSC = driWaitForMSC32,
732 .WaitForSBC = NULL,
733 .SwapBuffersMSC = NULL
734 };
735
736 /*
737 * This is the bootstrap function for the driver.
738 * The __driCreateScreen name is the symbol that libGL.so fetches.
739 * Return: pointer to a __DRIscreenPrivate.
740 *
741 */
742 #if !defined(DRI_NEW_INTERFACE_ONLY)
743 void *__driCreateScreen(Display * dpy, int scrn, __DRIscreen * psc,
744 int numConfigs, __GLXvisualConfig * config)
745 {
746 __DRIscreenPrivate *psp;
747 psp =
748 __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI);
749 return (void *)psp;
750 }
751 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
752
753 /**
754 * This is the bootstrap function for the driver. libGL supplies all of the
755 * requisite information about the system, and the driver initializes itself.
756 * This routine also fills in the linked list pointed to by \c driver_modes
757 * with the \c __GLcontextModes that the driver can support for windows or
758 * pbuffers.
759 *
760 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
761 * failure.
762 */
763 #ifdef USE_NEW_INTERFACE
764 void *__driCreateNewScreen(__DRInativeDisplay * dpy, int scrn,
765 __DRIscreen * psc, const __GLcontextModes * modes,
766 const __DRIversion * ddx_version,
767 const __DRIversion * dri_version,
768 const __DRIversion * drm_version,
769 const __DRIframebuffer * frame_buffer,
770 drmAddress pSAREA, int fd, int internal_api_version,
771 __GLcontextModes ** driver_modes)
772 {
773 __DRIscreenPrivate *psp;
774 static const __DRIversion ddx_expected = { 4, 0, 0 };
775 static const __DRIversion dri_expected = { 4, 0, 0 };
776 static const __DRIversion drm_expected = { 1, 11, 1 };
777
778 if (!driCheckDriDdxDrmVersions2("R300",
779 dri_version, &dri_expected,
780 ddx_version, &ddx_expected,
781 drm_version, &drm_expected)) {
782 return NULL;
783 }
784
785 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
786 ddx_version, dri_version, drm_version,
787 frame_buffer, pSAREA, fd,
788 internal_api_version, &radeonAPI);
789 if (psp != NULL) {
790 create_context_modes = (PFNGLXCREATECONTEXTMODES)
791 glXGetProcAddress((const GLubyte *)
792 "__glXCreateContextModes");
793 if (create_context_modes != NULL) {
794 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
795 *driver_modes = radeonFillInModes(dri_priv->bpp,
796 (dri_priv->bpp ==
797 16) ? 16 : 24,
798 (dri_priv->bpp ==
799 16) ? 0 : 8,
800 (dri_priv->backOffset !=
801 dri_priv->
802 depthOffset));
803 }
804 }
805
806 return (void *)psp;
807 }
808 #endif /* USE_NEW_INTERFACE */
809
810 /**
811 * Get information about previous buffer swaps.
812 */
813 static int getSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
814 {
815 radeonContextPtr radeon;
816
817 if ((dPriv == NULL) || (dPriv->driContextPriv == NULL)
818 || (dPriv->driContextPriv->driverPrivate == NULL)
819 || (sInfo == NULL)) {
820 return -1;
821 }
822
823 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
824 sInfo->swap_count = radeon->swap_count;
825 sInfo->swap_ust = radeon->swap_ust;
826 sInfo->swap_missed_count = radeon->swap_missed_count;
827
828 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
829 ? driCalculateSwapUsage(dPriv, 0, radeon->swap_missed_ust)
830 : 0.0;
831
832 return 0;
833 }