1 /**************************************************************************
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
5 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
7 The Weather Channel (TM) funded Tungsten Graphics to develop the
8 initial release of the Radeon 8500 driver under the XFree86 license.
9 This notice must be preserved.
13 Permission is hereby granted, free of charge, to any person obtaining
14 a copy of this software and associated documentation files (the
15 "Software"), to deal in the Software without restriction, including
16 without limitation the rights to use, copy, modify, merge, publish,
17 distribute, sublicense, and/or sell copies of the Software, and to
18 permit persons to whom the Software is furnished to do so, subject to
19 the following conditions:
21 The above copyright notice and this permission notice (including the
22 next paragraph) shall be included in all copies or substantial
23 portions of the Software.
25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
29 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 **************************************************************************/
35 #include "radeon_common.h"
36 #include "xmlpool.h" /* for symbolic values of enum-type options */
39 #include "main/state.h"
41 #define DRIVER_DATE "20090101"
44 int RADEON_DEBUG
= (0);
47 /* Return various strings for glGetString().
49 static const GLubyte
*radeonGetString(GLcontext
* ctx
, GLenum name
)
51 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
52 static char buffer
[128];
56 if (IS_R300_CLASS(radeon
->radeonScreen
))
57 return (GLubyte
*) "DRI R300 Project";
59 return (GLubyte
*) "Tungsten Graphics, Inc.";
64 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
65 radeon
->radeonScreen
->AGPMode
;
68 if (IS_R300_CLASS(radeon
->radeonScreen
))
70 else if (IS_R200_CLASS(radeon
->radeonScreen
))
75 offset
= driGetRendererString(buffer
, chipname
, DRIVER_DATE
,
78 if (IS_R300_CLASS(radeon
->radeonScreen
)) {
79 sprintf(&buffer
[offset
], " %sTCL",
80 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
83 sprintf(&buffer
[offset
], " %sTCL",
84 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
88 if (radeon
->radeonScreen
->driScreen
->dri2
.enabled
)
89 strcat(buffer
, " DRI2");
91 return (GLubyte
*) buffer
;
99 /* Initialize the driver's misc functions.
101 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
103 functions
->GetString
= radeonGetString
;
107 * Create and initialize all common fields of the context,
108 * including the Mesa context itself.
110 GLboolean
radeonInitContext(radeonContextPtr radeon
,
111 struct dd_function_table
* functions
,
112 const __GLcontextModes
* glVisual
,
113 __DRIcontextPrivate
* driContextPriv
,
114 void *sharedContextPrivate
)
116 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
117 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
122 /* Fill in additional standard functions. */
123 radeonInitDriverFuncs(functions
);
125 radeon
->radeonScreen
= screen
;
126 /* Allocate and initialize the Mesa context */
127 if (sharedContextPrivate
)
128 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
131 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
132 functions
, (void *)radeon
);
137 driContextPriv
->driverPrivate
= radeon
;
140 radeon
->dri
.context
= driContextPriv
;
141 radeon
->dri
.screen
= sPriv
;
142 radeon
->dri
.drawable
= NULL
;
143 radeon
->dri
.readable
= NULL
;
144 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
145 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
146 radeon
->dri
.fd
= sPriv
->fd
;
147 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
149 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
150 screen
->sarea_priv_offset
);
153 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
154 radeon
->iw
.irq_seq
= -1;
155 radeon
->irqsEmitted
= 0;
156 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
157 radeon
->radeonScreen
->irq
);
159 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
161 if (!radeon
->do_irqs
)
163 "IRQ's not enabled, falling back to %s: %d %d\n",
164 radeon
->do_usleeps
? "usleeps" : "busy waits",
165 fthrottle_mode
, radeon
->radeonScreen
->irq
);
167 radeon
->texture_depth
= driQueryOptioni (&radeon
->optionCache
,
169 if (radeon
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
170 radeon
->texture_depth
= ( glVisual
->rgbBits
> 16 ) ?
171 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
177 * Cleanup common context fields.
178 * Called by r200DestroyContext/r300DestroyContext
180 void radeonCleanupContext(radeonContextPtr radeon
)
182 #ifdef RADEON_BO_TRACK
185 struct radeon_renderbuffer
*rb
;
186 struct radeon_framebuffer
*rfb
;
188 /* free the Mesa context */
189 _mesa_destroy_context(radeon
->glCtx
);
191 rfb
= (void*)radeon
->dri
.drawable
->driverPrivate
;
192 rb
= rfb
->color_rb
[0];
194 radeon_bo_unref(rb
->bo
);
197 rb
= rfb
->color_rb
[1];
199 radeon_bo_unref(rb
->bo
);
202 rb
= radeon_get_renderbuffer(&rfb
->base
, BUFFER_DEPTH
);
204 radeon_bo_unref(rb
->bo
);
207 rfb
= (void*)radeon
->dri
.readable
->driverPrivate
;
208 rb
= rfb
->color_rb
[0];
210 radeon_bo_unref(rb
->bo
);
213 rb
= rfb
->color_rb
[1];
215 radeon_bo_unref(rb
->bo
);
218 rb
= radeon_get_renderbuffer(&rfb
->base
, BUFFER_DEPTH
);
220 radeon_bo_unref(rb
->bo
);
224 /* _mesa_destroy_context() might result in calls to functions that
225 * depend on the DriverCtx, so don't set it to NULL before.
227 * radeon->glCtx->DriverCtx = NULL;
232 /* free the option cache */
233 driDestroyOptionCache(&radeon
->optionCache
);
235 rcommonDestroyCmdBuf(radeon
);
237 if (radeon
->state
.scissor
.pClipRects
) {
238 FREE(radeon
->state
.scissor
.pClipRects
);
239 radeon
->state
.scissor
.pClipRects
= 0;
241 #ifdef RADEON_BO_TRACK
242 track
= fopen("/tmp/tracklog", "w");
244 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
250 /* Force the context `c' to be unbound from its buffer.
252 GLboolean
radeonUnbindContext(__DRIcontextPrivate
* driContextPriv
)
254 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
256 if (RADEON_DEBUG
& DEBUG_DRI
)
257 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,
265 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
266 struct radeon_framebuffer
*draw
)
268 /* if radeon->fake */
269 struct radeon_renderbuffer
*rb
;
271 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
273 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
274 radeon
->radeonScreen
->frontOffset
,
277 RADEON_GEM_DOMAIN_VRAM
,
280 rb
->cpp
= radeon
->radeonScreen
->cpp
;
281 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
283 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
285 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
286 radeon
->radeonScreen
->backOffset
,
289 RADEON_GEM_DOMAIN_VRAM
,
292 rb
->cpp
= radeon
->radeonScreen
->cpp
;
293 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
295 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
297 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
298 radeon
->radeonScreen
->depthOffset
,
301 RADEON_GEM_DOMAIN_VRAM
,
304 rb
->cpp
= radeon
->radeonScreen
->cpp
;
305 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
307 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
309 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
310 radeon
->radeonScreen
->depthOffset
,
313 RADEON_GEM_DOMAIN_VRAM
,
316 rb
->cpp
= radeon
->radeonScreen
->cpp
;
317 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
322 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
323 struct radeon_framebuffer
*draw
)
325 int size
= 4096*4096*4;
326 /* if radeon->fake */
327 struct radeon_renderbuffer
*rb
;
329 if (radeon
->radeonScreen
->kernel_mm
) {
330 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
335 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
337 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
338 radeon
->radeonScreen
->frontOffset
+
339 radeon
->radeonScreen
->fbLocation
,
342 RADEON_GEM_DOMAIN_VRAM
,
345 rb
->cpp
= radeon
->radeonScreen
->cpp
;
346 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
348 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
350 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
351 radeon
->radeonScreen
->backOffset
+
352 radeon
->radeonScreen
->fbLocation
,
355 RADEON_GEM_DOMAIN_VRAM
,
358 rb
->cpp
= radeon
->radeonScreen
->cpp
;
359 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
361 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
363 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
364 radeon
->radeonScreen
->depthOffset
+
365 radeon
->radeonScreen
->fbLocation
,
368 RADEON_GEM_DOMAIN_VRAM
,
371 rb
->cpp
= radeon
->radeonScreen
->cpp
;
372 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
374 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
376 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
377 radeon
->radeonScreen
->depthOffset
+
378 radeon
->radeonScreen
->fbLocation
,
381 RADEON_GEM_DOMAIN_VRAM
,
384 rb
->cpp
= radeon
->radeonScreen
->cpp
;
385 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
391 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
)
393 unsigned int attachments
[10];
394 __DRIbuffer
*buffers
;
396 struct radeon_renderbuffer
*rb
;
398 struct radeon_framebuffer
*draw
;
399 radeonContextPtr radeon
;
401 struct radeon_bo
*depth_bo
, *bo
;
403 if (RADEON_DEBUG
& DEBUG_DRI
)
404 fprintf(stderr
, "enter %s, drawable %p\n", __func__
, drawable
);
406 draw
= drawable
->driverPrivate
;
407 screen
= context
->driScreenPriv
;
408 radeon
= (radeonContextPtr
) context
->driverPrivate
;
410 if (draw
->color_rb
[0])
411 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
412 if (draw
->color_rb
[1])
413 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
414 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
))
415 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
416 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
))
417 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
419 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
424 drawable
->loaderPrivate
);
428 /* set one cliprect to cover the whole drawable */
433 drawable
->numClipRects
= 1;
434 drawable
->pClipRects
[0].x1
= 0;
435 drawable
->pClipRects
[0].y1
= 0;
436 drawable
->pClipRects
[0].x2
= drawable
->w
;
437 drawable
->pClipRects
[0].y2
= drawable
->h
;
438 drawable
->numBackClipRects
= 1;
439 drawable
->pBackClipRects
[0].x1
= 0;
440 drawable
->pBackClipRects
[0].y1
= 0;
441 drawable
->pBackClipRects
[0].x2
= drawable
->w
;
442 drawable
->pBackClipRects
[0].y2
= drawable
->h
;
443 for (i
= 0; i
< count
; i
++) {
444 switch (buffers
[i
].attachment
) {
445 case __DRI_BUFFER_FRONT_LEFT
:
446 rb
= draw
->color_rb
[0];
447 regname
= "dri2 front buffer";
449 case __DRI_BUFFER_BACK_LEFT
:
450 rb
= draw
->color_rb
[1];
451 regname
= "dri2 back buffer";
453 case __DRI_BUFFER_DEPTH
:
454 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
455 regname
= "dri2 depth buffer";
457 case __DRI_BUFFER_STENCIL
:
458 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
459 regname
= "dri2 stencil buffer";
461 case __DRI_BUFFER_ACCUM
:
464 "unhandled buffer attach event, attacment type %d\n",
465 buffers
[i
].attachment
);
473 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
474 if (name
== buffers
[i
].name
)
478 if (RADEON_DEBUG
& DEBUG_DRI
)
480 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
481 regname
, buffers
[i
].name
, buffers
[i
].attachment
,
482 buffers
[i
].cpp
, buffers
[i
].pitch
);
484 rb
->cpp
= buffers
[i
].cpp
;
485 rb
->pitch
= buffers
[i
].pitch
;
486 rb
->width
= drawable
->w
;
487 rb
->height
= drawable
->h
;
490 if (buffers
[i
].attachment
== __DRI_BUFFER_STENCIL
&& depth_bo
) {
491 if (RADEON_DEBUG
& DEBUG_DRI
)
492 fprintf(stderr
, "(reusing depth buffer as stencil)\n");
496 bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
500 RADEON_GEM_DOMAIN_VRAM
,
504 fprintf(stderr
, "failed to attach %s %d\n",
505 regname
, buffers
[i
].name
);
510 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH
)
513 radeon_renderbuffer_set_bo(rb
, bo
);
518 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
521 /* Force the context `c' to be the current context and associate with it
524 GLboolean
radeonMakeCurrent(__DRIcontextPrivate
* driContextPriv
,
525 __DRIdrawablePrivate
* driDrawPriv
,
526 __DRIdrawablePrivate
* driReadPriv
)
528 radeonContextPtr radeon
;
529 struct radeon_framebuffer
*drfb
;
530 struct gl_framebuffer
*readfb
;
532 if (!driContextPriv
) {
533 if (RADEON_DEBUG
& DEBUG_DRI
)
534 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
535 _mesa_make_current(NULL
, NULL
, NULL
);
539 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
540 drfb
= driDrawPriv
->driverPrivate
;
541 readfb
= driReadPriv
->driverPrivate
;
543 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
544 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
);
545 if (driDrawPriv
!= driReadPriv
)
546 radeon_update_renderbuffers(driContextPriv
, driReadPriv
);
547 radeon
->state
.color
.rrb
=
548 radeon_get_renderbuffer(&drfb
->base
, BUFFER_BACK_LEFT
);
549 radeon
->state
.depth
.rrb
=
550 radeon_get_renderbuffer(&drfb
->base
, BUFFER_DEPTH
);
552 radeon_make_renderbuffer_current(radeon
, drfb
);
556 if (RADEON_DEBUG
& DEBUG_DRI
)
557 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__
, radeon
->glCtx
, drfb
, readfb
);
559 if (radeon
->dri
.readable
!= driReadPriv
)
560 radeon
->dri
.readable
= driReadPriv
;
562 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
563 if (driReadPriv
!= driDrawPriv
)
564 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
566 _mesa_make_current(radeon
->glCtx
, &drfb
->base
, readfb
);
568 _mesa_update_state(radeon
->glCtx
);
570 if (radeon
->glCtx
->DrawBuffer
== &drfb
->base
) {
572 if (radeon
->dri
.drawable
!= driDrawPriv
) {
573 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
575 driDrawPriv
->vblFlags
=
576 (radeon
->radeonScreen
->irq
!= 0)
577 ? driGetDefaultVBlankFlags(&radeon
->
579 : VBLANK_FLAG_NO_IRQ
;
581 driDrawableInitVBlank(driDrawPriv
);
582 drfb
->vbl_waited
= driDrawPriv
->vblSeq
;
584 for (i
= 0; i
< 2; i
++) {
585 if (drfb
->color_rb
[i
])
586 drfb
->color_rb
[i
]->vbl_pending
= driDrawPriv
->vblSeq
;
590 radeon
->dri
.drawable
= driDrawPriv
;
592 radeon_window_moved(radeon
);
594 radeon_draw_buffer(radeon
->glCtx
, &drfb
->base
);
598 if (RADEON_DEBUG
& DEBUG_DRI
)
599 fprintf(stderr
, "End %s\n", __FUNCTION__
);