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
);
171 * Cleanup common context fields.
172 * Called by r200DestroyContext/r300DestroyContext
174 void radeonCleanupContext(radeonContextPtr radeon
)
176 #ifdef RADEON_BO_TRACK
179 struct radeon_renderbuffer
*rb
;
180 struct radeon_framebuffer
*rfb
;
182 /* free the Mesa context */
183 _mesa_destroy_context(radeon
->glCtx
);
185 rfb
= (void*)radeon
->dri
.drawable
->driverPrivate
;
186 rb
= rfb
->color_rb
[0];
188 radeon_bo_unref(rb
->bo
);
191 rb
= rfb
->color_rb
[1];
193 radeon_bo_unref(rb
->bo
);
196 rb
= radeon_get_renderbuffer(&rfb
->base
, BUFFER_DEPTH
);
198 radeon_bo_unref(rb
->bo
);
201 rfb
= (void*)radeon
->dri
.readable
->driverPrivate
;
202 rb
= rfb
->color_rb
[0];
204 radeon_bo_unref(rb
->bo
);
207 rb
= rfb
->color_rb
[1];
209 radeon_bo_unref(rb
->bo
);
212 rb
= radeon_get_renderbuffer(&rfb
->base
, BUFFER_DEPTH
);
214 radeon_bo_unref(rb
->bo
);
218 /* _mesa_destroy_context() might result in calls to functions that
219 * depend on the DriverCtx, so don't set it to NULL before.
221 * radeon->glCtx->DriverCtx = NULL;
226 /* free the option cache */
227 driDestroyOptionCache(&radeon
->optionCache
);
229 rcommonDestroyCmdBuf(radeon
);
231 if (radeon
->state
.scissor
.pClipRects
) {
232 FREE(radeon
->state
.scissor
.pClipRects
);
233 radeon
->state
.scissor
.pClipRects
= 0;
235 #ifdef RADEON_BO_TRACK
236 track
= fopen("/tmp/tracklog", "w");
238 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
244 /* Force the context `c' to be unbound from its buffer.
246 GLboolean
radeonUnbindContext(__DRIcontextPrivate
* driContextPriv
)
248 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
250 if (RADEON_DEBUG
& DEBUG_DRI
)
251 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,
259 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
260 struct radeon_framebuffer
*draw
)
262 /* if radeon->fake */
263 struct radeon_renderbuffer
*rb
;
265 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
267 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
268 radeon
->radeonScreen
->frontOffset
,
271 RADEON_GEM_DOMAIN_VRAM
,
274 rb
->cpp
= radeon
->radeonScreen
->cpp
;
275 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
277 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
279 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
280 radeon
->radeonScreen
->backOffset
,
283 RADEON_GEM_DOMAIN_VRAM
,
286 rb
->cpp
= radeon
->radeonScreen
->cpp
;
287 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
289 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
291 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
292 radeon
->radeonScreen
->depthOffset
,
295 RADEON_GEM_DOMAIN_VRAM
,
298 rb
->cpp
= radeon
->radeonScreen
->cpp
;
299 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
301 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
303 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
304 radeon
->radeonScreen
->depthOffset
,
307 RADEON_GEM_DOMAIN_VRAM
,
310 rb
->cpp
= radeon
->radeonScreen
->cpp
;
311 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
316 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
317 struct radeon_framebuffer
*draw
)
319 int size
= 4096*4096*4;
320 /* if radeon->fake */
321 struct radeon_renderbuffer
*rb
;
323 if (radeon
->radeonScreen
->kernel_mm
) {
324 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
329 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
331 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
332 radeon
->radeonScreen
->frontOffset
+
333 radeon
->radeonScreen
->fbLocation
,
336 RADEON_GEM_DOMAIN_VRAM
,
339 rb
->cpp
= radeon
->radeonScreen
->cpp
;
340 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
342 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
344 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
345 radeon
->radeonScreen
->backOffset
+
346 radeon
->radeonScreen
->fbLocation
,
349 RADEON_GEM_DOMAIN_VRAM
,
352 rb
->cpp
= radeon
->radeonScreen
->cpp
;
353 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
355 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
357 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
358 radeon
->radeonScreen
->depthOffset
+
359 radeon
->radeonScreen
->fbLocation
,
362 RADEON_GEM_DOMAIN_VRAM
,
365 rb
->cpp
= radeon
->radeonScreen
->cpp
;
366 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
368 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
370 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
371 radeon
->radeonScreen
->depthOffset
+
372 radeon
->radeonScreen
->fbLocation
,
375 RADEON_GEM_DOMAIN_VRAM
,
378 rb
->cpp
= radeon
->radeonScreen
->cpp
;
379 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
385 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
)
387 unsigned int attachments
[10];
388 __DRIbuffer
*buffers
;
390 struct radeon_renderbuffer
*rb
;
392 struct radeon_framebuffer
*draw
;
393 radeonContextPtr radeon
;
396 if (RADEON_DEBUG
& DEBUG_DRI
)
397 fprintf(stderr
, "enter %s, drawable %p\n", __func__
, drawable
);
399 draw
= drawable
->driverPrivate
;
400 screen
= context
->driScreenPriv
;
401 radeon
= (radeonContextPtr
) context
->driverPrivate
;
403 if (draw
->color_rb
[0])
404 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
405 if (draw
->color_rb
[1])
406 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
407 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
))
408 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
409 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
))
410 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
412 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
417 drawable
->loaderPrivate
);
421 /* set one cliprect to cover the whole drawable */
426 drawable
->numClipRects
= 1;
427 drawable
->pClipRects
[0].x1
= 0;
428 drawable
->pClipRects
[0].y1
= 0;
429 drawable
->pClipRects
[0].x2
= drawable
->w
;
430 drawable
->pClipRects
[0].y2
= drawable
->h
;
431 drawable
->numBackClipRects
= 1;
432 drawable
->pBackClipRects
[0].x1
= 0;
433 drawable
->pBackClipRects
[0].y1
= 0;
434 drawable
->pBackClipRects
[0].x2
= drawable
->w
;
435 drawable
->pBackClipRects
[0].y2
= drawable
->h
;
436 for (i
= 0; i
< count
; i
++) {
437 switch (buffers
[i
].attachment
) {
438 case __DRI_BUFFER_FRONT_LEFT
:
439 rb
= draw
->color_rb
[0];
440 regname
= "dri2 front buffer";
442 case __DRI_BUFFER_BACK_LEFT
:
443 rb
= draw
->color_rb
[1];
444 regname
= "dri2 back buffer";
446 case __DRI_BUFFER_DEPTH
:
447 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
448 regname
= "dri2 depth buffer";
450 case __DRI_BUFFER_STENCIL
:
451 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
452 regname
= "dri2 stencil buffer";
454 case __DRI_BUFFER_ACCUM
:
457 "unhandled buffer attach event, attacment type %d\n",
458 buffers
[i
].attachment
);
466 radeon_bo_unref(rb
->bo
);
469 rb
->cpp
= buffers
[i
].cpp
;
470 rb
->pitch
= buffers
[i
].pitch
;
471 rb
->width
= drawable
->w
;
472 rb
->height
= drawable
->h
;
474 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
478 RADEON_GEM_DOMAIN_VRAM
,
480 if (rb
->bo
== NULL
) {
481 fprintf(stderr
, "failed to attach %s %d\n",
482 regname
, buffers
[i
].name
);
487 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
490 /* Force the context `c' to be the current context and associate with it
493 GLboolean
radeonMakeCurrent(__DRIcontextPrivate
* driContextPriv
,
494 __DRIdrawablePrivate
* driDrawPriv
,
495 __DRIdrawablePrivate
* driReadPriv
)
497 radeonContextPtr radeon
;
498 struct radeon_framebuffer
*drfb
;
499 struct gl_framebuffer
*readfb
;
501 if (!driContextPriv
) {
502 if (RADEON_DEBUG
& DEBUG_DRI
)
503 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
504 _mesa_make_current(NULL
, NULL
, NULL
);
508 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
509 drfb
= driDrawPriv
->driverPrivate
;
510 readfb
= driReadPriv
->driverPrivate
;
512 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
513 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
);
514 if (driDrawPriv
!= driReadPriv
)
515 radeon_update_renderbuffers(driContextPriv
, driReadPriv
);
516 radeon
->state
.color
.rrb
=
517 radeon_get_renderbuffer(&drfb
->base
, BUFFER_BACK_LEFT
);
518 radeon
->state
.depth
.rrb
=
519 radeon_get_renderbuffer(&drfb
->base
, BUFFER_DEPTH
);
521 radeon_make_renderbuffer_current(radeon
, drfb
);
525 if (RADEON_DEBUG
& DEBUG_DRI
)
526 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__
, radeon
->glCtx
, drfb
, readfb
);
528 if (radeon
->dri
.readable
!= driReadPriv
)
529 radeon
->dri
.readable
= driReadPriv
;
531 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
532 if (driReadPriv
!= driDrawPriv
)
533 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
535 _mesa_make_current(radeon
->glCtx
, &drfb
->base
, readfb
);
537 _mesa_update_state(radeon
->glCtx
);
539 if (radeon
->glCtx
->DrawBuffer
== &drfb
->base
) {
541 if (radeon
->dri
.drawable
!= driDrawPriv
) {
542 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
544 driDrawPriv
->vblFlags
=
545 (radeon
->radeonScreen
->irq
!= 0)
546 ? driGetDefaultVBlankFlags(&radeon
->
548 : VBLANK_FLAG_NO_IRQ
;
550 driDrawableInitVBlank(driDrawPriv
);
551 drfb
->vbl_waited
= driDrawPriv
->vblSeq
;
553 for (i
= 0; i
< 2; i
++) {
554 if (drfb
->color_rb
[i
])
555 drfb
->color_rb
[i
]->vbl_pending
= driDrawPriv
->vblSeq
;
559 radeon
->dri
.drawable
= driDrawPriv
;
561 radeon_window_moved(radeon
);
563 radeon_draw_buffer(radeon
->glCtx
, &drfb
->base
);
567 if (RADEON_DEBUG
& DEBUG_DRI
)
568 fprintf(stderr
, "End %s\n", __FUNCTION__
);