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_context.c
32 * Common context initialization.
34 * \author Keith Whitwell <keith@tungstengraphics.com>
44 #include "framebuffer.h"
46 #include "drivers/common/driverfuncs.h"
47 #include "swrast/swrast.h"
49 #include "radeon_screen.h"
50 #include "radeon_ioctl.h"
51 #include "radeon_macros.h"
52 #include "radeon_reg.h"
54 #include "r300_state.h"
58 #include "xmlpool.h" /* for symbolic values of enum-type options */
60 #define DRIVER_DATE "20060815"
63 /* Return various strings for glGetString().
65 static const GLubyte
*radeonGetString(GLcontext
* ctx
, GLenum name
)
67 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
68 static char buffer
[128];
72 return (GLubyte
*) "Tungsten Graphics, Inc.";
77 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
78 radeon
->radeonScreen
->AGPMode
;
81 if (IS_R300_CLASS(radeon
->radeonScreen
))
86 offset
= driGetRendererString(buffer
, chipname
, DRIVER_DATE
,
89 sprintf(&buffer
[offset
], " %sTCL",
90 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
93 return (GLubyte
*) buffer
;
101 /* Initialize the driver's misc functions.
103 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
105 functions
->GetString
= radeonGetString
;
110 * Create and initialize all common fields of the context,
111 * including the Mesa context itself.
113 GLboolean
radeonInitContext(radeonContextPtr radeon
,
114 struct dd_function_table
* functions
,
115 const __GLcontextModes
* glVisual
,
116 __DRIcontextPrivate
* driContextPriv
,
117 void *sharedContextPrivate
)
119 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
120 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
125 /* Fill in additional standard functions. */
126 radeonInitDriverFuncs(functions
);
128 /* Allocate and initialize the Mesa context */
129 if (sharedContextPrivate
)
130 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
133 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
134 functions
, (void *)radeon
);
139 driContextPriv
->driverPrivate
= radeon
;
142 radeon
->dri
.context
= driContextPriv
;
143 radeon
->dri
.screen
= sPriv
;
144 radeon
->dri
.drawable
= NULL
;
145 radeon
->dri
.readable
= NULL
;
146 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
147 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
148 radeon
->dri
.fd
= sPriv
->fd
;
149 radeon
->dri
.drmMinor
= sPriv
->drmMinor
;
151 radeon
->radeonScreen
= screen
;
152 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
153 screen
->sarea_priv_offset
);
156 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
157 radeon
->iw
.irq_seq
= -1;
158 radeon
->irqsEmitted
= 0;
159 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
160 radeon
->radeonScreen
->irq
);
162 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
164 if (!radeon
->do_irqs
)
166 "IRQ's not enabled, falling back to %s: %d %d\n",
167 radeon
->do_usleeps
? "usleeps" : "busy waits",
168 fthrottle_mode
, radeon
->radeonScreen
->irq
);
170 radeon
->vblank_flags
= (radeon
->radeonScreen
->irq
!= 0)
171 ? driGetDefaultVBlankFlags(&radeon
->optionCache
) : VBLANK_FLAG_NO_IRQ
;
173 (*dri_interface
->getUST
) (&radeon
->swap_ust
);
180 * Cleanup common context fields.
181 * Called by r200DestroyContext/r300DestroyContext
183 void radeonCleanupContext(radeonContextPtr radeon
)
185 /* _mesa_destroy_context() might result in calls to functions that
186 * depend on the DriverCtx, so don't set it to NULL before.
188 * radeon->glCtx->DriverCtx = NULL;
191 /* free the Mesa context */
192 _mesa_destroy_context(radeon
->glCtx
);
194 if (radeon
->state
.scissor
.pClipRects
) {
195 FREE(radeon
->state
.scissor
.pClipRects
);
196 radeon
->state
.scissor
.pClipRects
= 0;
202 * Swap front and back buffer.
204 void radeonSwapBuffers(__DRIdrawablePrivate
* dPriv
)
206 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
207 radeonContextPtr radeon
;
210 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
213 if (ctx
->Visual
.doubleBufferMode
) {
214 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
215 if (radeon
->doPageFlip
) {
216 radeonPageFlip(dPriv
);
218 radeonCopyBuffer(dPriv
, NULL
);
222 /* XXX this shouldn't be an error but we can't handle it for now */
223 _mesa_problem(NULL
, "%s: drawable has no context!",
228 void radeonCopySubBuffer(__DRIdrawablePrivate
* dPriv
,
229 int x
, int y
, int w
, int h
)
231 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
232 radeonContextPtr radeon
;
235 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
238 if (ctx
->Visual
.doubleBufferMode
) {
239 drm_clip_rect_t rect
;
240 rect
.x1
= x
+ dPriv
->x
;
241 rect
.y1
= (dPriv
->h
- y
- h
) + dPriv
->y
;
242 rect
.x2
= rect
.x1
+ w
;
243 rect
.y2
= rect
.y1
+ h
;
244 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
245 radeonCopyBuffer(dPriv
, &rect
);
248 /* XXX this shouldn't be an error but we can't handle it for now */
249 _mesa_problem(NULL
, "%s: drawable has no context!",
254 /* Force the context `c' to be the current context and associate with it
257 GLboolean
radeonMakeCurrent(__DRIcontextPrivate
* driContextPriv
,
258 __DRIdrawablePrivate
* driDrawPriv
,
259 __DRIdrawablePrivate
* driReadPriv
)
261 if (driContextPriv
) {
262 radeonContextPtr radeon
=
263 (radeonContextPtr
) driContextPriv
->driverPrivate
;
265 if (RADEON_DEBUG
& DEBUG_DRI
)
266 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,
269 if (radeon
->dri
.drawable
!= driDrawPriv
) {
270 driDrawableInitVBlank(driDrawPriv
,
271 radeon
->vblank_flags
,
275 if (radeon
->dri
.drawable
!= driDrawPriv
||
276 radeon
->dri
.readable
!= driReadPriv
) {
277 radeon
->dri
.drawable
= driDrawPriv
;
278 radeon
->dri
.readable
= driReadPriv
;
280 r300UpdateWindow(radeon
->glCtx
);
281 r300UpdateViewportOffset(radeon
->glCtx
);
284 _mesa_make_current(radeon
->glCtx
,
285 (GLframebuffer
*) driDrawPriv
->
287 (GLframebuffer
*) driReadPriv
->
290 if (!radeon
->glCtx
->Viewport
.Width
) {
291 _mesa_set_viewport(radeon
->glCtx
, 0, 0,
292 driDrawPriv
->w
, driDrawPriv
->h
);
295 _mesa_update_state(radeon
->glCtx
);
297 if (RADEON_DEBUG
& DEBUG_DRI
)
298 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
299 _mesa_make_current(0, 0, 0);
302 if (RADEON_DEBUG
& DEBUG_DRI
)
303 fprintf(stderr
, "End %s\n", __FUNCTION__
);
307 /* Force the context `c' to be unbound from its buffer.
309 GLboolean
radeonUnbindContext(__DRIcontextPrivate
* driContextPriv
)
311 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
313 if (RADEON_DEBUG
& DEBUG_DRI
)
314 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,