2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
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.
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:
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.
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.
28 **************************************************************************/
31 * \file radeon_screen.c
32 * Screen initialization functions for the R200 driver.
34 * \author Keith Whitwell <keith@tungstengraphics.com>
43 #include "framebuffer.h"
44 #include "renderbuffer.h"
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"
58 #include "GL/internal/dri_interface.h"
59 #include "drirenderbuffer.h"
65 const char __driR200ConfigOptions
[] =
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)
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
)
81 DRI_CONF_SECTION_DEBUG
82 DRI_CONF_NO_RAST(false)
84 DRI_CONF_SECTION_SOFTWARE
85 DRI_CONF_ARB_VERTEX_PROGRAM(true)
86 DRI_CONF_NV_VERTEX_PROGRAM(false)
89 static const GLuint __driR200NConfigOptions
= 13;
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") \
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") \
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)") \
111 const char __driR300ConfigOptions
[] =
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)
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
)
129 DRI_CONF_SECTION_DEBUG
130 DRI_CONF_NO_RAST(false)
133 static const GLuint __driR300NConfigOptions
= 13;
137 int RADEON_DEBUG
= 0;
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
},
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 */
162 /* Including xf86PciInfo.h introduces a bunch of errors...
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 ? */
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
217 #ifdef USE_NEW_INTERFACE
218 static PFNGLXCREATECONTEXTMODES create_context_modes
= NULL
;
219 #endif /* USE_NEW_INTERFACE */
221 static radeonScreenPtr __radeonScreen
;
223 static int getSwapInfo(__DRIdrawablePrivate
* dPriv
, __DRIswapInfo
* sInfo
);
225 #ifdef USE_NEW_INTERFACE
226 static __GLcontextModes
*radeonFillInModes(unsigned pixel_bits
,
228 unsigned stencil_bits
,
229 GLboolean have_back_buffer
)
231 __GLcontextModes
*modes
;
234 unsigned depth_buffer_factor
;
235 unsigned back_buffer_factor
;
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.
244 static const GLenum back_buffer_modes
[] = {
245 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
/*, GLX_SWAP_COPY_OML */
248 uint8_t depth_bits_array
[2];
249 uint8_t stencil_bits_array
[2];
251 depth_bits_array
[0] = depth_bits
;
252 depth_bits_array
[1] = depth_bits
;
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
258 stencil_bits_array
[0] = 0;
259 stencil_bits_array
[1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
261 depth_buffer_factor
= ((depth_bits
!= 0)
262 || (stencil_bits
!= 0)) ? 2 : 1;
263 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
265 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
267 if (pixel_bits
== 16) {
269 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
272 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
275 modes
= (*create_context_modes
) (num_modes
, sizeof(__GLcontextModes
));
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__
,
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__
,
295 /* Mark the visual as slow if there are "fake" stencil bits.
297 for (m
= modes
; m
!= NULL
; m
= m
->next
) {
298 if ((m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
)) {
299 m
->visualRating
= GLX_SLOW_CONFIG
;
305 #endif /* USE_NEW_INTERFACE */
307 /* Create the device specific screen private data struct.
309 static radeonScreenPtr
radeonCreateScreen(__DRIscreenPrivate
* sPriv
)
311 radeonScreenPtr screen
;
312 RADEONDRIPtr dri_priv
= (RADEONDRIPtr
) sPriv
->pDevPriv
;
313 unsigned char *RADEONMMIO
;
315 /* Allocate the private area */
316 screen
= (radeonScreenPtr
) CALLOC(sizeof(*screen
));
319 ("%s: Could not allocate memory for screen structure",
325 RADEON_DEBUG
= driParseDebugString(getenv("RADEON_DEBUG"), debug_control
);
328 /* Get family and potential quirks from the PCI device ID.
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");
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
;
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
;
372 /* TODO: Check all those chips for the exact flags required.
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
;
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
;
396 case PCI_CHIP_R420_JK
:
397 screen
->chipset
= RADEON_CHIP_R420
;
402 "Unknown device ID %04X, please report. Assuming plain R300.\n",
404 screen
->chipset
= RADEON_CHIP_R300
;
407 /* Parse configuration */
408 if (GET_CHIP(screen
) >= RADEON_CHIP_R300
) {
409 driParseOptionInfo(&screen
->optionCache
,
410 __driR300ConfigOptions
, __driR300NConfigOptions
);
412 driParseOptionInfo(&screen
->optionCache
,
413 __driR200ConfigOptions
, __driR200NConfigOptions
);
416 /* This is first since which regions we map depends on whether or
417 * not we are using a PCI card.
419 screen
->IsPCI
= dri_priv
->IsPCI
;
423 drm_radeon_getparam_t gp
;
425 gp
.param
= RADEON_PARAM_GART_BUFFER_OFFSET
;
426 gp
.value
= &screen
->gart_buffer_offset
;
428 ret
= drmCommandWriteRead(sPriv
->fd
, DRM_RADEON_GETPARAM
,
433 "drmRadeonGetParam (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n",
438 if (sPriv
->drmMinor
>= 6) {
439 gp
.param
= RADEON_PARAM_GART_BASE
;
440 gp
.value
= &screen
->gart_base
;
443 drmCommandWriteRead(sPriv
->fd
, DRM_RADEON_GETPARAM
,
448 "drmR200GetParam (RADEON_PARAM_GART_BASE): %d\n",
453 gp
.param
= RADEON_PARAM_IRQ_NR
;
454 gp
.value
= &screen
->irq
;
457 drmCommandWriteRead(sPriv
->fd
, DRM_RADEON_GETPARAM
,
462 "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n",
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);
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
)) {
481 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__
);
485 RADEONMMIO
= screen
->mmio
.map
;
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
);
494 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__
);
497 screen
->scratch
= (__volatile__
uint32_t *)
498 ((GLubyte
*) screen
->status
.map
+ RADEON_SCRATCH_REG_OFFSET
);
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
);
505 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__
);
509 if (dri_priv
->gartTexHandle
&& dri_priv
->gartTexMapSize
) {
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
);
522 ("%s: drmMAP failed for GART texture area\n",
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));
533 screen
->cpp
= dri_priv
->bpp
/ 8;
534 screen
->AGPMode
= dri_priv
->AGPMode
;
536 screen
->fbLocation
= (INREG(RADEON_MC_FB_LOCATION
) & 0xffff) << 16;
538 if (sPriv
->drmMinor
>= 10) {
539 drm_radeon_setparam_t sp
;
541 sp
.param
= RADEON_SETPARAM_FB_LOCATION
;
542 sp
.value
= screen
->fbLocation
;
544 drmCommandWrite(sPriv
->fd
, DRM_RADEON_SETPARAM
,
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
;
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
;
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;
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
;
576 screen
->driScreen
= sPriv
;
577 screen
->sarea_priv_offset
= dri_priv
->sarea_priv_offset
;
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
;
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");
596 (*glx_enable_extension
) (psc
,
597 "GLX_MESA_swap_frame_usage");
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
;
608 (*glx_enable_extension
) (psc
,
609 "GLX_MESA_allocate_memory");
613 if (driCompareGLXAPIVersion(20030915) >= 0) {
614 (*glx_enable_extension
) (psc
,
615 "GLX_SGIX_fbconfig");
616 (*glx_enable_extension
) (psc
,
617 "GLX_OML_swap_method");
624 /* Destroy the device specific screen private data struct.
626 static void radeonDestroyScreen(__DRIscreenPrivate
* sPriv
)
628 radeonScreenPtr screen
= (radeonScreenPtr
) sPriv
->private;
633 if (screen
->gartTextures
.map
) {
634 drmUnmap(screen
->gartTextures
.map
, screen
->gartTextures
.size
);
636 drmUnmapBufs(screen
->buffers
);
637 drmUnmap(screen
->status
.map
, screen
->status
.size
);
638 drmUnmap(screen
->mmio
.map
, screen
->mmio
.size
);
640 /* free all option information */
641 driDestroyOptionInfo(&screen
->optionCache
);
644 sPriv
->private = NULL
;
647 /* Initialize the driver specific screen private data.
649 static GLboolean
radeonInitDriver(__DRIscreenPrivate
* sPriv
)
651 __radeonScreen
= radeonCreateScreen(sPriv
);
653 sPriv
->private = (void *)__radeonScreen
;
655 return sPriv
->private ? GL_TRUE
: GL_FALSE
;
659 * Create and initialize the Mesa and driver specific pixmap buffer
662 * \todo This function (and its interface) will need to be updated to support
666 radeonCreateBuffer(__DRIscreenPrivate
* driScrnPriv
,
667 __DRIdrawablePrivate
* driDrawPriv
,
668 const __GLcontextModes
* mesaVis
, GLboolean isPixmap
)
670 radeonScreenPtr screen
= (radeonScreenPtr
)driScrnPriv
->private;
673 return GL_FALSE
; /* not implemented */
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;
681 driDrawPriv
->driverPrivate
= (void *)
682 _mesa_create_framebuffer(mesaVis
,
684 swStencil
, swAccum
, swAlpha
);
686 struct gl_framebuffer
*fb
= _mesa_create_framebuffer(mesaVis
);
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
);
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
);
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
);
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
);
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
);
724 _mesa_add_soft_renderbuffers(fb
,
725 GL_FALSE
, /* color */
731 driDrawPriv
->driverPrivate
= (void *) fb
;
733 return (driDrawPriv
->driverPrivate
!= NULL
);
737 static void radeonDestroyBuffer(__DRIdrawablePrivate
* driDrawPriv
)
739 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->
745 * Choose the appropriate CreateContext function based on the chipset.
747 static GLboolean
radeonCreateContext(const __GLcontextModes
* glVisual
,
748 __DRIcontextPrivate
* driContextPriv
,
749 void *sharedContextPriv
)
751 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
752 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
753 int chip
= GET_CHIP(screen
);
755 if (chip
>= RADEON_CHIP_R300
)
756 return r300CreateContext(glVisual
, driContextPriv
, sharedContextPriv
);
759 return r200CreateContext(glVisual
, driContextPriv
, sharedContextPriv
);
765 * Choose the appropriate DestroyContext function based on the chipset.
767 static void radeonDestroyContext(__DRIcontextPrivate
* driContextPriv
)
769 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
770 int chip
= GET_CHIP(radeon
->radeonScreen
);
772 if (chip
>= RADEON_CHIP_R300
)
773 return r300DestroyContext(driContextPriv
);
776 return r200DestroyContext(driContextPriv
);
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
,
795 .SwapBuffersMSC
= NULL
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.
804 #if !defined(DRI_NEW_INTERFACE_ONLY)
805 void *__driCreateScreen(Display
* dpy
, int scrn
, __DRIscreen
* psc
,
806 int numConfigs
, __GLXvisualConfig
* config
)
808 __DRIscreenPrivate
*psp
;
810 __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &radeonAPI
);
813 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
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
822 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
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
)
835 __DRIscreenPrivate
*psp
;
836 static const __DRIversion ddx_expected
= { 4, 0, 0 };
837 static const __DRIversion dri_expected
= { 4, 0, 0 };
838 static const __DRIversion drm_expected
= { 1, 11, 1 };
840 if (!driCheckDriDdxDrmVersions2("R300",
841 dri_version
, &dri_expected
,
842 ddx_version
, &ddx_expected
,
843 drm_version
, &drm_expected
)) {
847 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
848 ddx_version
, dri_version
, drm_version
,
849 frame_buffer
, pSAREA
, fd
,
850 internal_api_version
, &radeonAPI
);
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
,
862 (dri_priv
->backOffset
!=
870 #endif /* USE_NEW_INTERFACE */
873 * Get information about previous buffer swaps.
875 static int getSwapInfo(__DRIdrawablePrivate
* dPriv
, __DRIswapInfo
* sInfo
)
877 radeonContextPtr radeon
;
879 if ((dPriv
== NULL
) || (dPriv
->driContextPriv
== NULL
)
880 || (dPriv
->driContextPriv
->driverPrivate
== NULL
)
881 || (sInfo
== NULL
)) {
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
;
890 sInfo
->swap_missed_usage
= (sInfo
->swap_missed_count
!= 0)
891 ? driCalculateSwapUsage(dPriv
, 0, radeon
->swap_missed_ust
)