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 "drirenderbuffer.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/state.h"
43 #include "main/simple_list.h"
44 #include "swrast/swrast.h"
45 #include "swrast_setup/swrast_setup.h"
48 #define DRIVER_DATE "20090101"
51 int RADEON_DEBUG
= (0);
54 /* Return various strings for glGetString().
56 static const GLubyte
*radeonGetString(GLcontext
* ctx
, GLenum name
)
58 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
59 static char buffer
[128];
63 if (IS_R300_CLASS(radeon
->radeonScreen
))
64 return (GLubyte
*) "DRI R300 Project";
66 return (GLubyte
*) "Tungsten Graphics, Inc.";
71 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
72 radeon
->radeonScreen
->AGPMode
;
75 if (IS_R300_CLASS(radeon
->radeonScreen
))
77 else if (IS_R200_CLASS(radeon
->radeonScreen
))
82 offset
= driGetRendererString(buffer
, chipname
, DRIVER_DATE
,
85 if (IS_R300_CLASS(radeon
->radeonScreen
)) {
86 sprintf(&buffer
[offset
], " %sTCL",
87 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
90 sprintf(&buffer
[offset
], " %sTCL",
91 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
95 if (radeon
->radeonScreen
->driScreen
->dri2
.enabled
)
96 strcat(buffer
, " DRI2");
98 return (GLubyte
*) buffer
;
106 /* Initialize the driver's misc functions.
108 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
110 functions
->GetString
= radeonGetString
;
114 * Create and initialize all common fields of the context,
115 * including the Mesa context itself.
117 GLboolean
radeonInitContext(radeonContextPtr radeon
,
118 struct dd_function_table
* functions
,
119 const __GLcontextModes
* glVisual
,
120 __DRIcontextPrivate
* driContextPriv
,
121 void *sharedContextPrivate
)
123 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
124 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
129 /* Fill in additional standard functions. */
130 radeonInitDriverFuncs(functions
);
132 radeon
->radeonScreen
= screen
;
133 /* Allocate and initialize the Mesa context */
134 if (sharedContextPrivate
)
135 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
138 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
139 functions
, (void *)radeon
);
144 driContextPriv
->driverPrivate
= radeon
;
147 radeon
->dri
.context
= driContextPriv
;
148 radeon
->dri
.screen
= sPriv
;
149 radeon
->dri
.drawable
= NULL
;
150 radeon
->dri
.readable
= NULL
;
151 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
152 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
153 radeon
->dri
.fd
= sPriv
->fd
;
154 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
156 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
157 screen
->sarea_priv_offset
);
160 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
161 radeon
->iw
.irq_seq
= -1;
162 radeon
->irqsEmitted
= 0;
163 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
164 radeon
->radeonScreen
->irq
);
166 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
168 if (!radeon
->do_irqs
)
170 "IRQ's not enabled, falling back to %s: %d %d\n",
171 radeon
->do_usleeps
? "usleeps" : "busy waits",
172 fthrottle_mode
, radeon
->radeonScreen
->irq
);
174 radeon
->texture_depth
= driQueryOptioni (&radeon
->optionCache
,
176 if (radeon
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
177 radeon
->texture_depth
= ( glVisual
->rgbBits
> 16 ) ?
178 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
180 radeon
->texture_row_align
= 32;
188 * Destroy the command buffer and state atoms.
190 static void radeon_destroy_atom_list(radeonContextPtr radeon
)
192 struct radeon_state_atom
*atom
;
194 foreach(atom
, &radeon
->hw
.atomlist
) {
203 * Cleanup common context fields.
204 * Called by r200DestroyContext/r300DestroyContext
206 void radeonDestroyContext(__DRIcontextPrivate
*driContextPriv
)
208 #ifdef RADEON_BO_TRACK
211 GET_CURRENT_CONTEXT(ctx
);
212 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
213 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
215 if (radeon
== current
) {
216 radeon_firevertices(radeon
);
217 _mesa_make_current(NULL
, NULL
, NULL
);
223 if (radeon
->dma
.current
) {
224 rcommonFlushCmdBuf( radeon
, __FUNCTION__
);
227 radeonReleaseArrays(radeon
->glCtx
, ~0);
229 if (radeon
->vtbl
.free_context
)
230 radeon
->vtbl
.free_context(radeon
->glCtx
);
231 _swsetup_DestroyContext( radeon
->glCtx
);
232 _tnl_DestroyContext( radeon
->glCtx
);
233 _vbo_DestroyContext( radeon
->glCtx
);
234 _swrast_DestroyContext( radeon
->glCtx
);
236 radeonDestroyBuffer(radeon
->dri
.drawable
);
237 radeonDestroyBuffer(radeon
->dri
.readable
);
240 /* free the Mesa context */
241 _mesa_destroy_context(radeon
->glCtx
);
243 /* _mesa_destroy_context() might result in calls to functions that
244 * depend on the DriverCtx, so don't set it to NULL before.
246 * radeon->glCtx->DriverCtx = NULL;
248 /* free the option cache */
249 driDestroyOptionCache(&radeon
->optionCache
);
251 rcommonDestroyCmdBuf(radeon
);
253 radeon_destroy_atom_list(radeon
);
255 if (radeon
->state
.scissor
.pClipRects
) {
256 FREE(radeon
->state
.scissor
.pClipRects
);
257 radeon
->state
.scissor
.pClipRects
= 0;
260 #ifdef RADEON_BO_TRACK
261 track
= fopen("/tmp/tracklog", "w");
263 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
270 /* Force the context `c' to be unbound from its buffer.
272 GLboolean
radeonUnbindContext(__DRIcontextPrivate
* driContextPriv
)
274 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
276 if (RADEON_DEBUG
& DEBUG_DRI
)
277 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,
285 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
286 struct radeon_framebuffer
*draw
)
288 /* if radeon->fake */
289 struct radeon_renderbuffer
*rb
;
291 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
293 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
294 radeon
->radeonScreen
->frontOffset
,
297 RADEON_GEM_DOMAIN_VRAM
,
300 rb
->cpp
= radeon
->radeonScreen
->cpp
;
301 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
303 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
305 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
306 radeon
->radeonScreen
->backOffset
,
309 RADEON_GEM_DOMAIN_VRAM
,
312 rb
->cpp
= radeon
->radeonScreen
->cpp
;
313 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
315 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
317 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
318 radeon
->radeonScreen
->depthOffset
,
321 RADEON_GEM_DOMAIN_VRAM
,
324 rb
->cpp
= radeon
->radeonScreen
->cpp
;
325 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
327 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
329 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
330 radeon
->radeonScreen
->depthOffset
,
333 RADEON_GEM_DOMAIN_VRAM
,
336 rb
->cpp
= radeon
->radeonScreen
->cpp
;
337 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
342 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
343 struct radeon_framebuffer
*draw
)
345 int size
= 4096*4096*4;
346 /* if radeon->fake */
347 struct radeon_renderbuffer
*rb
;
349 if (radeon
->radeonScreen
->kernel_mm
) {
350 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
355 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
357 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
358 radeon
->radeonScreen
->frontOffset
+
359 radeon
->radeonScreen
->fbLocation
,
362 RADEON_GEM_DOMAIN_VRAM
,
365 rb
->cpp
= radeon
->radeonScreen
->cpp
;
366 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
368 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
370 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
371 radeon
->radeonScreen
->backOffset
+
372 radeon
->radeonScreen
->fbLocation
,
375 RADEON_GEM_DOMAIN_VRAM
,
378 rb
->cpp
= radeon
->radeonScreen
->cpp
;
379 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
381 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
383 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
384 radeon
->radeonScreen
->depthOffset
+
385 radeon
->radeonScreen
->fbLocation
,
388 RADEON_GEM_DOMAIN_VRAM
,
391 rb
->cpp
= radeon
->radeonScreen
->cpp
;
392 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
394 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
396 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
397 radeon
->radeonScreen
->depthOffset
+
398 radeon
->radeonScreen
->fbLocation
,
401 RADEON_GEM_DOMAIN_VRAM
,
404 rb
->cpp
= radeon
->radeonScreen
->cpp
;
405 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
411 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
)
413 unsigned int attachments
[10];
414 __DRIbuffer
*buffers
;
416 struct radeon_renderbuffer
*rb
;
418 struct radeon_framebuffer
*draw
;
419 radeonContextPtr radeon
;
421 struct radeon_bo
*depth_bo
= NULL
, *bo
;
423 if (RADEON_DEBUG
& DEBUG_DRI
)
424 fprintf(stderr
, "enter %s, drawable %p\n", __func__
, drawable
);
426 draw
= drawable
->driverPrivate
;
427 screen
= context
->driScreenPriv
;
428 radeon
= (radeonContextPtr
) context
->driverPrivate
;
430 if (draw
->color_rb
[0])
431 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
432 if (draw
->color_rb
[1])
433 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
434 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
))
435 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
436 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
))
437 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
439 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
444 drawable
->loaderPrivate
);
448 /* set one cliprect to cover the whole drawable */
453 drawable
->numClipRects
= 1;
454 drawable
->pClipRects
[0].x1
= 0;
455 drawable
->pClipRects
[0].y1
= 0;
456 drawable
->pClipRects
[0].x2
= drawable
->w
;
457 drawable
->pClipRects
[0].y2
= drawable
->h
;
458 drawable
->numBackClipRects
= 1;
459 drawable
->pBackClipRects
[0].x1
= 0;
460 drawable
->pBackClipRects
[0].y1
= 0;
461 drawable
->pBackClipRects
[0].x2
= drawable
->w
;
462 drawable
->pBackClipRects
[0].y2
= drawable
->h
;
463 for (i
= 0; i
< count
; i
++) {
464 switch (buffers
[i
].attachment
) {
465 case __DRI_BUFFER_FRONT_LEFT
:
466 rb
= draw
->color_rb
[0];
467 regname
= "dri2 front buffer";
469 case __DRI_BUFFER_BACK_LEFT
:
470 rb
= draw
->color_rb
[1];
471 regname
= "dri2 back buffer";
473 case __DRI_BUFFER_DEPTH
:
474 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
475 regname
= "dri2 depth buffer";
477 case __DRI_BUFFER_STENCIL
:
478 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
479 regname
= "dri2 stencil buffer";
481 case __DRI_BUFFER_ACCUM
:
484 "unhandled buffer attach event, attacment type %d\n",
485 buffers
[i
].attachment
);
493 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
494 if (name
== buffers
[i
].name
)
498 if (RADEON_DEBUG
& DEBUG_DRI
)
500 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
501 regname
, buffers
[i
].name
, buffers
[i
].attachment
,
502 buffers
[i
].cpp
, buffers
[i
].pitch
);
504 rb
->cpp
= buffers
[i
].cpp
;
505 rb
->pitch
= buffers
[i
].pitch
;
506 rb
->width
= drawable
->w
;
507 rb
->height
= drawable
->h
;
510 if (buffers
[i
].attachment
== __DRI_BUFFER_STENCIL
&& depth_bo
) {
511 if (RADEON_DEBUG
& DEBUG_DRI
)
512 fprintf(stderr
, "(reusing depth buffer as stencil)\n");
516 bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
520 RADEON_GEM_DOMAIN_VRAM
,
524 fprintf(stderr
, "failed to attach %s %d\n",
525 regname
, buffers
[i
].name
);
530 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH
) {
531 if (draw
->base
.Visual
.depthBits
== 16)
536 radeon_renderbuffer_set_bo(rb
, bo
);
541 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
544 /* Force the context `c' to be the current context and associate with it
547 GLboolean
radeonMakeCurrent(__DRIcontextPrivate
* driContextPriv
,
548 __DRIdrawablePrivate
* driDrawPriv
,
549 __DRIdrawablePrivate
* driReadPriv
)
551 radeonContextPtr radeon
;
552 struct radeon_framebuffer
*drfb
;
553 struct gl_framebuffer
*readfb
;
555 if (!driContextPriv
) {
556 if (RADEON_DEBUG
& DEBUG_DRI
)
557 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
558 _mesa_make_current(NULL
, NULL
, NULL
);
562 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
563 drfb
= driDrawPriv
->driverPrivate
;
564 readfb
= driReadPriv
->driverPrivate
;
566 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
567 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
);
568 if (driDrawPriv
!= driReadPriv
)
569 radeon_update_renderbuffers(driContextPriv
, driReadPriv
);
570 radeon
->state
.color
.rrb
=
571 radeon_get_renderbuffer(&drfb
->base
, BUFFER_BACK_LEFT
);
572 radeon
->state
.depth
.rrb
=
573 radeon_get_renderbuffer(&drfb
->base
, BUFFER_DEPTH
);
575 radeon_make_renderbuffer_current(radeon
, drfb
);
579 if (RADEON_DEBUG
& DEBUG_DRI
)
580 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__
, radeon
->glCtx
, drfb
, readfb
);
582 if (radeon
->dri
.readable
!= driReadPriv
)
583 radeon
->dri
.readable
= driReadPriv
;
585 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
586 if (driReadPriv
!= driDrawPriv
)
587 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
589 _mesa_make_current(radeon
->glCtx
, &drfb
->base
, readfb
);
591 _mesa_update_state(radeon
->glCtx
);
593 if (radeon
->glCtx
->DrawBuffer
== &drfb
->base
) {
595 if (radeon
->dri
.drawable
!= driDrawPriv
) {
596 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
598 driDrawPriv
->vblFlags
=
599 (radeon
->radeonScreen
->irq
!= 0)
600 ? driGetDefaultVBlankFlags(&radeon
->
602 : VBLANK_FLAG_NO_IRQ
;
604 driDrawableInitVBlank(driDrawPriv
);
605 drfb
->vbl_waited
= driDrawPriv
->vblSeq
;
607 for (i
= 0; i
< 2; i
++) {
608 if (drfb
->color_rb
[i
])
609 drfb
->color_rb
[i
]->vbl_pending
= driDrawPriv
->vblSeq
;
613 radeon
->dri
.drawable
= driDrawPriv
;
615 radeon_window_moved(radeon
);
617 radeon_draw_buffer(radeon
->glCtx
, &drfb
->base
);
621 if (RADEON_DEBUG
& DEBUG_DRI
)
622 fprintf(stderr
, "End %s\n", __FUNCTION__
);