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>
39 #include "main/glheader.h"
40 #include "main/imports.h"
41 #include "main/context.h"
42 #include "main/state.h"
43 #include "main/matrix.h"
44 #include "main/framebuffer.h"
46 #include "drivers/common/driverfuncs.h"
47 #include "swrast/swrast.h"
49 #include "radeon_buffer.h"
50 #include "radeon_screen.h"
51 #include "radeon_ioctl.h"
52 #include "radeon_macros.h"
53 #include "radeon_reg.h"
55 #include "radeon_state.h"
56 #include "r300_state.h"
60 #include "xmlpool.h" /* for symbolic values of enum-type options */
61 #include "drirenderbuffer.h"
63 #define DRIVER_DATE "20060815"
66 /* Return various strings for glGetString().
68 static const GLubyte
*radeonGetString(GLcontext
* ctx
, GLenum name
)
70 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
71 static char buffer
[128];
75 if (IS_R300_CLASS(radeon
->radeonScreen
))
76 return (GLubyte
*) "DRI R300 Project";
78 return (GLubyte
*) "Tungsten Graphics, Inc.";
83 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
84 radeon
->radeonScreen
->AGPMode
;
87 if (IS_R300_CLASS(radeon
->radeonScreen
))
92 offset
= driGetRendererString(buffer
, chipname
, DRIVER_DATE
,
95 if (IS_R300_CLASS(radeon
->radeonScreen
)) {
96 sprintf(&buffer
[offset
], " %sTCL",
97 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
100 sprintf(&buffer
[offset
], " %sTCL",
101 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
105 return (GLubyte
*) buffer
;
113 /* Initialize the driver's misc functions.
115 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
117 functions
->GetString
= radeonGetString
;
122 * Create and initialize all common fields of the context,
123 * including the Mesa context itself.
125 GLboolean
radeonInitContext(radeonContextPtr radeon
,
126 struct dd_function_table
* functions
,
127 const __GLcontextModes
* glVisual
,
128 __DRIcontextPrivate
* driContextPriv
,
129 void *sharedContextPrivate
)
131 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
132 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
137 /* Fill in additional standard functions. */
138 radeonInitDriverFuncs(functions
);
140 radeon
->radeonScreen
= screen
;
141 /* Allocate and initialize the Mesa context */
142 if (sharedContextPrivate
)
143 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
146 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
147 functions
, (void *)radeon
);
152 driContextPriv
->driverPrivate
= radeon
;
155 radeon
->dri
.context
= driContextPriv
;
156 radeon
->dri
.screen
= sPriv
;
157 radeon
->dri
.drawable
= NULL
;
158 radeon
->dri
.readable
= NULL
;
159 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
160 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
161 radeon
->dri
.fd
= sPriv
->fd
;
162 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
164 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
165 screen
->sarea_priv_offset
);
168 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
169 radeon
->iw
.irq_seq
= -1;
170 radeon
->irqsEmitted
= 0;
171 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
172 radeon
->radeonScreen
->irq
);
174 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
176 if (!radeon
->do_irqs
)
178 "IRQ's not enabled, falling back to %s: %d %d\n",
179 radeon
->do_usleeps
? "usleeps" : "busy waits",
180 fthrottle_mode
, radeon
->radeonScreen
->irq
);
182 (*sPriv
->systemTime
->getUST
) (&radeon
->swap_ust
);
189 * Cleanup common context fields.
190 * Called by r200DestroyContext/r300DestroyContext
192 void radeonCleanupContext(radeonContextPtr radeon
)
194 /* _mesa_destroy_context() might result in calls to functions that
195 * depend on the DriverCtx, so don't set it to NULL before.
197 * radeon->glCtx->DriverCtx = NULL;
200 /* free the Mesa context */
201 _mesa_destroy_context(radeon
->glCtx
);
203 if (radeon
->state
.scissor
.pClipRects
) {
204 FREE(radeon
->state
.scissor
.pClipRects
);
205 radeon
->state
.scissor
.pClipRects
= 0;
211 * Swap front and back buffer.
213 void radeonSwapBuffers(__DRIdrawablePrivate
* dPriv
)
215 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
216 radeonContextPtr radeon
;
219 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
222 if (ctx
->Visual
.doubleBufferMode
) {
223 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
224 if (radeon
->doPageFlip
) {
225 radeonPageFlip(dPriv
);
227 radeonCopyBuffer(dPriv
, NULL
);
231 /* XXX this shouldn't be an error but we can't handle it for now */
232 _mesa_problem(NULL
, "%s: drawable has no context!",
237 void radeonCopySubBuffer(__DRIdrawablePrivate
* dPriv
,
238 int x
, int y
, int w
, int h
)
240 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
241 radeonContextPtr radeon
;
244 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
247 if (ctx
->Visual
.doubleBufferMode
) {
248 drm_clip_rect_t rect
;
249 rect
.x1
= x
+ dPriv
->x
;
250 rect
.y1
= (dPriv
->h
- y
- h
) + dPriv
->y
;
251 rect
.x2
= rect
.x1
+ w
;
252 rect
.y2
= rect
.y1
+ h
;
253 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
254 radeonCopyBuffer(dPriv
, &rect
);
257 /* XXX this shouldn't be an error but we can't handle it for now */
258 _mesa_problem(NULL
, "%s: drawable has no context!",
264 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
267 int size
= 4096*4096*4;
268 /* if radeon->fake */
269 struct radeon_renderbuffer
*rb
;
271 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
274 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
275 radeon
->radeonScreen
->frontOffset
+
276 radeon
->radeonScreen
->fbLocation
,
281 rb
->cpp
= radeon
->radeonScreen
->cpp
;
282 rb
->pitch
= radeon
->radeonScreen
->frontPitch
;
284 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
286 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
287 radeon
->radeonScreen
->backOffset
+
288 radeon
->radeonScreen
->fbLocation
,
293 rb
->cpp
= radeon
->radeonScreen
->cpp
;
294 rb
->pitch
= radeon
->radeonScreen
->backPitch
;
296 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
298 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
299 radeon
->radeonScreen
->depthOffset
+
300 radeon
->radeonScreen
->fbLocation
,
305 rb
->cpp
= radeon
->radeonScreen
->cpp
;
306 rb
->pitch
= radeon
->radeonScreen
->depthPitch
;
311 /* Force the context `c' to be the current context and associate with it
314 GLboolean
radeonMakeCurrent(__DRIcontextPrivate
* driContextPriv
,
315 __DRIdrawablePrivate
* driDrawPriv
,
316 __DRIdrawablePrivate
* driReadPriv
)
318 radeonContextPtr radeon
;
319 GLframebuffer
*dfb
, *rfb
;
321 if (!driContextPriv
) {
322 if (RADEON_DEBUG
& DEBUG_DRI
)
323 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
324 _mesa_make_current(NULL
, NULL
, NULL
);
328 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
329 dfb
= driDrawPriv
->driverPrivate
;
330 rfb
= driReadPriv
->driverPrivate
;
332 if (RADEON_DEBUG
& DEBUG_DRI
)
333 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
, radeon
->glCtx
);
335 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
336 if (driReadPriv
!= driDrawPriv
)
337 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
339 radeon_make_renderbuffer_current(radeon
, dfb
);
341 _mesa_make_current(radeon
->glCtx
, dfb
, rfb
);
343 if (radeon
->dri
.drawable
!= driDrawPriv
) {
344 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
345 driDrawPriv
->vblFlags
=
346 (radeon
->radeonScreen
->irq
!= 0)
347 ? driGetDefaultVBlankFlags(&radeon
->
349 : VBLANK_FLAG_NO_IRQ
;
351 driDrawableInitVBlank(driDrawPriv
);
355 radeon
->dri
.readable
= driReadPriv
;
357 if (radeon
->dri
.drawable
!= driDrawPriv
||
358 radeon
->lastStamp
!= driDrawPriv
->lastStamp
) {
359 radeon
->dri
.drawable
= driDrawPriv
;
361 radeonSetCliprects(radeon
);
362 r300UpdateViewportOffset(radeon
->glCtx
);
365 _mesa_update_state(radeon
->glCtx
);
367 radeonUpdatePageFlipping(radeon
);
369 if (RADEON_DEBUG
& DEBUG_DRI
)
370 fprintf(stderr
, "End %s\n", __FUNCTION__
);
374 /* Force the context `c' to be unbound from its buffer.
376 GLboolean
radeonUnbindContext(__DRIcontextPrivate
* driContextPriv
)
378 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
380 if (RADEON_DEBUG
& DEBUG_DRI
)
381 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,