1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.6 2002/12/16 16:18:58 dawes Exp $ */
2 /**************************************************************************
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
33 * Kevin E. Martin <martin@valinux.com>
34 * Gareth Hughes <gareth@valinux.com>
41 #include "radeon_context.h"
42 #include "radeon_screen.h"
43 #include "radeon_macros.h"
50 #include "glxextensions.h"
54 /* Including xf86PciInfo.h introduces a bunch of errors...
56 #define PCI_CHIP_RADEON_QD 0x5144
57 #define PCI_CHIP_RADEON_QE 0x5145
58 #define PCI_CHIP_RADEON_QF 0x5146
59 #define PCI_CHIP_RADEON_QG 0x5147
61 #define PCI_CHIP_RADEON_QY 0x5159
62 #define PCI_CHIP_RADEON_QZ 0x515A
64 #define PCI_CHIP_RADEON_LW 0x4C57 /* mobility 7 - has tcl */
66 #define PCI_CHIP_RADEON_LY 0x4C59
67 #define PCI_CHIP_RADEON_LZ 0x4C5A
69 #define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */
72 static int getSwapInfo( __DRIdrawablePrivate
*dPriv
, __DRIswapInfo
* sInfo
);
74 /* Create the device specific screen private data struct.
76 radeonScreenPtr
radeonCreateScreen( __DRIscreenPrivate
*sPriv
)
78 radeonScreenPtr screen
;
79 RADEONDRIPtr dri_priv
= (RADEONDRIPtr
)sPriv
->pDevPriv
;
81 if ( ! driCheckDriDdxDrmVersions( sPriv
, "Radeon", 4, 0, 4, 0, 1, 3 ) )
84 /* Allocate the private area */
85 screen
= (radeonScreenPtr
) CALLOC( sizeof(*screen
) );
87 __driUtilMessage("%s: Could not allocate memory for screen structure",
92 if ( sPriv
->drmMinor
< 3 ||
93 getenv("RADEON_COMPAT")) {
94 fprintf( stderr
, "Radeon DRI driver:\n\t"
95 "Compatibility mode for DRM driver version %d.%d.%d\n\t"
96 "TCL will be disabled, expect reduced performance\n\t"
97 "(prefer DRM radeon.o 1.3.x or newer)\n\t",
98 sPriv
->drmMajor
, sPriv
->drmMinor
, sPriv
->drmPatch
);
102 /* This is first since which regions we map depends on whether or
103 * not we are using a PCI card.
105 screen
->IsPCI
= dri_priv
->IsPCI
;
107 if (sPriv
->drmMinor
>= 3) {
109 drmRadeonGetParam gp
;
111 gp
.param
= RADEON_PARAM_AGP_BUFFER_OFFSET
;
112 gp
.value
= &screen
->agp_buffer_offset
;
114 ret
= drmCommandWriteRead( sPriv
->fd
, DRM_RADEON_GETPARAM
,
117 fprintf(stderr
, "drmRadeonGetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret
);
121 if (sPriv
->drmMinor
>= 6) {
122 gp
.param
= RADEON_PARAM_IRQ_NR
;
123 gp
.value
= &screen
->irq
;
125 ret
= drmCommandWriteRead( sPriv
->fd
, DRM_RADEON_GETPARAM
,
129 fprintf(stderr
, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret
);
135 screen
->mmio
.handle
= dri_priv
->registerHandle
;
136 screen
->mmio
.size
= dri_priv
->registerSize
;
137 if ( drmMap( sPriv
->fd
,
140 &screen
->mmio
.map
) ) {
142 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__
);
146 screen
->status
.handle
= dri_priv
->statusHandle
;
147 screen
->status
.size
= dri_priv
->statusSize
;
148 if ( drmMap( sPriv
->fd
,
149 screen
->status
.handle
,
151 &screen
->status
.map
) ) {
152 drmUnmap( screen
->mmio
.map
, screen
->mmio
.size
);
154 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__
);
157 screen
->scratch
= (__volatile__ CARD32
*)
158 ((GLubyte
*)screen
->status
.map
+ RADEON_SCRATCH_REG_OFFSET
);
160 screen
->buffers
= drmMapBufs( sPriv
->fd
);
161 if ( !screen
->buffers
) {
162 drmUnmap( screen
->status
.map
, screen
->status
.size
);
163 drmUnmap( screen
->mmio
.map
, screen
->mmio
.size
);
165 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__
);
169 if ( !screen
->IsPCI
) {
170 screen
->agpTextures
.handle
= dri_priv
->agpTexHandle
;
171 screen
->agpTextures
.size
= dri_priv
->agpTexMapSize
;
172 if ( drmMap( sPriv
->fd
,
173 screen
->agpTextures
.handle
,
174 screen
->agpTextures
.size
,
175 (drmAddressPtr
)&screen
->agpTextures
.map
) ) {
176 drmUnmapBufs( screen
->buffers
);
177 drmUnmap( screen
->status
.map
, screen
->status
.size
);
178 drmUnmap( screen
->mmio
.map
, screen
->mmio
.size
);
180 __driUtilMessage("%s: IsPCI failed\n", __FUNCTION__
);
186 switch ( dri_priv
->deviceID
) {
188 fprintf(stderr
, "unknown chip id, assuming full radeon support\n");
189 case PCI_CHIP_RADEON_QD
:
190 case PCI_CHIP_RADEON_QE
:
191 case PCI_CHIP_RADEON_QF
:
192 case PCI_CHIP_RADEON_QG
:
193 case PCI_CHIP_RV200_QW
:
194 case PCI_CHIP_RADEON_LW
:
195 screen
->chipset
|= RADEON_CHIPSET_TCL
;
196 case PCI_CHIP_RADEON_QY
:
197 case PCI_CHIP_RADEON_QZ
:
198 case PCI_CHIP_RADEON_LY
:
199 case PCI_CHIP_RADEON_LZ
:
203 screen
->cpp
= dri_priv
->bpp
/ 8;
204 screen
->AGPMode
= dri_priv
->AGPMode
;
206 screen
->frontOffset
= dri_priv
->frontOffset
;
207 screen
->frontPitch
= dri_priv
->frontPitch
;
208 screen
->backOffset
= dri_priv
->backOffset
;
209 screen
->backPitch
= dri_priv
->backPitch
;
210 screen
->depthOffset
= dri_priv
->depthOffset
;
211 screen
->depthPitch
= dri_priv
->depthPitch
;
213 screen
->texOffset
[RADEON_CARD_HEAP
] = dri_priv
->textureOffset
;
214 screen
->texSize
[RADEON_CARD_HEAP
] = dri_priv
->textureSize
;
215 screen
->logTexGranularity
[RADEON_CARD_HEAP
] =
216 dri_priv
->log2TexGran
;
219 || getenv( "RADEON_AGPTEXTURING_FORCE_DISABLE" ) ) {
220 screen
->numTexHeaps
= RADEON_NR_TEX_HEAPS
- 1;
221 screen
->texOffset
[RADEON_AGP_HEAP
] = 0;
222 screen
->texSize
[RADEON_AGP_HEAP
] = 0;
223 screen
->logTexGranularity
[RADEON_AGP_HEAP
] = 0;
225 screen
->numTexHeaps
= RADEON_NR_TEX_HEAPS
;
226 screen
->texOffset
[RADEON_AGP_HEAP
] =
227 dri_priv
->agpTexOffset
+ RADEON_AGP_TEX_OFFSET
;
228 screen
->texSize
[RADEON_AGP_HEAP
] = dri_priv
->agpTexMapSize
;
229 screen
->logTexGranularity
[RADEON_AGP_HEAP
] =
230 dri_priv
->log2AGPTexGran
;
233 screen
->driScreen
= sPriv
;
234 screen
->sarea_priv_offset
= dri_priv
->sarea_priv_offset
;
238 /* Destroy the device specific screen private data struct.
240 void radeonDestroyScreen( __DRIscreenPrivate
*sPriv
)
242 radeonScreenPtr screen
= (radeonScreenPtr
)sPriv
->private;
247 if ( !screen
->IsPCI
) {
248 drmUnmap( screen
->agpTextures
.map
,
249 screen
->agpTextures
.size
);
251 drmUnmapBufs( screen
->buffers
);
252 drmUnmap( screen
->status
.map
, screen
->status
.size
);
253 drmUnmap( screen
->mmio
.map
, screen
->mmio
.size
);
256 sPriv
->private = NULL
;
260 /* Initialize the driver specific screen private data.
263 radeonInitDriver( __DRIscreenPrivate
*sPriv
)
265 sPriv
->private = (void *) radeonCreateScreen( sPriv
);
266 if ( !sPriv
->private ) {
267 radeonDestroyScreen( sPriv
);
276 /* Create and initialize the Mesa and driver specific pixmap buffer
280 radeonCreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
281 __DRIdrawablePrivate
*driDrawPriv
,
282 const __GLcontextModes
*mesaVis
,
286 return GL_FALSE
; /* not implemented */
289 const GLboolean swDepth
= GL_FALSE
;
290 const GLboolean swAlpha
= GL_FALSE
;
291 const GLboolean swAccum
= mesaVis
->accumRedBits
> 0;
292 const GLboolean swStencil
= mesaVis
->stencilBits
> 0 &&
293 mesaVis
->depthBits
!= 24;
294 driDrawPriv
->driverPrivate
= (void *)
295 _mesa_create_framebuffer( mesaVis
,
300 return (driDrawPriv
->driverPrivate
!= NULL
);
306 radeonDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
308 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
314 /* Fullscreen mode isn't used for much -- could be a way to shrink
315 * front/back buffers & get more texture memory if the client has
316 * changed the video resolution.
318 * Pageflipping is now done automatically whenever there is a single
322 radeonOpenCloseFullScreen( __DRIcontextPrivate
*driContextPriv
)
327 static struct __DriverAPIRec radeonAPI
= {
328 .InitDriver
= radeonInitDriver
,
329 .DestroyScreen
= radeonDestroyScreen
,
330 .CreateContext
= radeonCreateContext
,
331 .DestroyContext
= radeonDestroyContext
,
332 .CreateBuffer
= radeonCreateBuffer
,
333 .DestroyBuffer
= radeonDestroyBuffer
,
334 .SwapBuffers
= radeonSwapBuffers
,
335 .MakeCurrent
= radeonMakeCurrent
,
336 .UnbindContext
= radeonUnbindContext
,
337 .OpenFullScreen
= radeonOpenCloseFullScreen
,
338 .CloseFullScreen
= radeonOpenCloseFullScreen
,
339 .GetSwapInfo
= getSwapInfo
,
340 .GetMSC
= driGetMSC32
,
341 .WaitForMSC
= driWaitForMSC32
,
343 .SwapBuffersMSC
= NULL
349 * This is the bootstrap function for the driver.
350 * The __driCreateScreen name is the symbol that libGL.so fetches.
351 * Return: pointer to a __DRIscreenPrivate.
354 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
355 int numConfigs
, __GLXvisualConfig
*config
)
357 __DRIscreenPrivate
*psp
;
358 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &radeonAPI
);
362 void *__driCreateScreen(struct DRIDriverRec
*driver
,
363 struct DRIDriverContextRec
*driverContext
)
365 __DRIscreenPrivate
*psp
;
366 psp
= __driUtilCreateScreen(driver
, driverContext
, &radeonAPI
);
373 /* This function is called by libGL.so as soon as libGL.so is loaded.
374 * This is where we'd register new extension functions with the dispatcher.
377 __driRegisterExtensions( void )
379 PFNGLXENABLEEXTENSIONPROC glx_enable_extension
;
382 if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) {
383 glx_enable_extension
= (PFNGLXENABLEEXTENSIONPROC
)
384 glXGetProcAddress( "__glXEnableExtension" );
386 if ( glx_enable_extension
!= NULL
) {
387 glx_enable_extension( "GLX_SGI_swap_control", GL_FALSE
);
388 glx_enable_extension( "GLX_SGI_video_sync", GL_FALSE
);
389 glx_enable_extension( "GLX_MESA_swap_control", GL_FALSE
);
390 glx_enable_extension( "GLX_MESA_swap_frame_usage", GL_FALSE
);
398 * Get information about previous buffer swaps.
401 getSwapInfo( __DRIdrawablePrivate
*dPriv
, __DRIswapInfo
* sInfo
)
403 radeonContextPtr rmesa
;
405 if ( (dPriv
== NULL
) || (dPriv
->driContextPriv
== NULL
)
406 || (dPriv
->driContextPriv
->driverPrivate
== NULL
)
407 || (sInfo
== NULL
) ) {
411 rmesa
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
412 sInfo
->swap_count
= rmesa
->swap_count
;
413 sInfo
->swap_ust
= rmesa
->swap_ust
;
414 sInfo
->swap_missed_count
= rmesa
->swap_missed_count
;
416 sInfo
->swap_missed_usage
= (sInfo
->swap_missed_count
!= 0)
417 ? driCalculateSwapUsage( dPriv
, 0, rmesa
->swap_missed_ust
)