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