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 */
38 #include "drivers/common/meta.h"
39 #include "main/context.h"
40 #include "main/framebuffer.h"
41 #include "main/fbobject.h"
42 #include "main/renderbuffer.h"
43 #include "main/state.h"
44 #include "util/simple_list.h"
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
50 int RADEON_DEBUG
= (0);
54 static const char* get_chip_family_name(int chip_family
)
57 #if defined(RADEON_R100)
58 case CHIP_FAMILY_R100
: return "R100";
59 case CHIP_FAMILY_RV100
: return "RV100";
60 case CHIP_FAMILY_RS100
: return "RS100";
61 case CHIP_FAMILY_RV200
: return "RV200";
62 case CHIP_FAMILY_RS200
: return "RS200";
63 #elif defined(RADEON_R200)
64 case CHIP_FAMILY_R200
: return "R200";
65 case CHIP_FAMILY_RV250
: return "RV250";
66 case CHIP_FAMILY_RS300
: return "RS300";
67 case CHIP_FAMILY_RV280
: return "RV280";
69 default: return "unknown";
73 const char const *radeonVendorString
= "Mesa Project";
75 /* Return complete renderer string.
77 const char *radeonGetRendererString(radeonScreenPtr radeonScreen
)
79 static char buffer
[128];
80 char hardwarename
[32];
82 GLuint agp_mode
= (radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
83 radeonScreen
->AGPMode
;
85 snprintf(hardwarename
, sizeof(hardwarename
), "%s (%s %04X)",
86 #if defined(RADEON_R100)
88 #elif defined(RADEON_R200)
91 get_chip_family_name(radeonScreen
->chip_family
),
92 radeonScreen
->device_id
);
94 driGetRendererString(buffer
, hardwarename
, agp_mode
);
96 strcat(buffer
, " DRI2");
102 /* Return various strings for glGetString().
104 static const GLubyte
*radeonGetString(struct gl_context
* ctx
, GLenum name
)
106 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
110 return (GLubyte
*) radeonVendorString
;
113 return (GLubyte
*) radeonGetRendererString(radeon
->radeonScreen
);
120 /* Initialize the driver's misc functions.
122 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
124 functions
->GetString
= radeonGetString
;
128 * Create and initialize all common fields of the context,
129 * including the Mesa context itself.
131 GLboolean
radeonInitContext(radeonContextPtr radeon
,
133 struct dd_function_table
* functions
,
134 const struct gl_config
* glVisual
,
135 __DRIcontext
* driContextPriv
,
136 void *sharedContextPrivate
)
138 __DRIscreen
*sPriv
= driContextPriv
->driScreenPriv
;
139 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->driverPrivate
);
140 struct gl_context
* ctx
;
141 struct gl_context
* shareCtx
;
144 /* Fill in additional standard functions. */
145 radeonInitDriverFuncs(functions
);
147 radeon
->radeonScreen
= screen
;
148 /* Allocate and initialize the Mesa context */
149 if (sharedContextPrivate
)
150 shareCtx
= &((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
154 if (!_mesa_initialize_context(&radeon
->glCtx
, api
,
159 ctx
= &radeon
->glCtx
;
160 driContextPriv
->driverPrivate
= radeon
;
162 _mesa_meta_init(ctx
);
165 radeon
->dri
.context
= driContextPriv
;
166 radeon
->dri
.screen
= sPriv
;
167 radeon
->dri
.fd
= sPriv
->fd
;
168 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
171 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
172 radeon
->iw
.irq_seq
= -1;
173 radeon
->irqsEmitted
= 0;
174 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
175 radeon
->radeonScreen
->irq
);
177 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
179 if (!radeon
->do_irqs
)
181 "IRQ's not enabled, falling back to %s: %d %d\n",
182 radeon
->do_usleeps
? "usleeps" : "busy waits",
183 fthrottle_mode
, radeon
->radeonScreen
->irq
);
185 radeon
->texture_depth
= driQueryOptioni (&radeon
->optionCache
,
187 if (radeon
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
188 radeon
->texture_depth
= ( glVisual
->rgbBits
> 16 ) ?
189 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
191 radeon
->texture_row_align
= 32;
192 radeon
->texture_rect_row_align
= 64;
193 radeon
->texture_compressed_row_align
= 32;
195 radeon_init_dma(radeon
);
203 * Destroy the command buffer and state atoms.
205 static void radeon_destroy_atom_list(radeonContextPtr radeon
)
207 struct radeon_state_atom
*atom
;
209 foreach(atom
, &radeon
->hw
.atomlist
) {
217 * Cleanup common context fields.
218 * Called by r200DestroyContext
220 void radeonDestroyContext(__DRIcontext
*driContextPriv
)
222 #ifdef RADEON_BO_TRACK
225 GET_CURRENT_CONTEXT(ctx
);
226 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
227 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
231 _mesa_meta_free(&radeon
->glCtx
);
233 if (radeon
== current
) {
234 _mesa_make_current(NULL
, NULL
, NULL
);
237 radeon_firevertices(radeon
);
238 if (!is_empty_list(&radeon
->dma
.reserved
)) {
239 rcommonFlushCmdBuf( radeon
, __FUNCTION__
);
242 radeonFreeDmaRegions(radeon
);
243 radeonReleaseArrays(&radeon
->glCtx
, ~0);
244 if (radeon
->vtbl
.free_context
)
245 radeon
->vtbl
.free_context(&radeon
->glCtx
);
246 _swsetup_DestroyContext( &radeon
->glCtx
);
247 _tnl_DestroyContext( &radeon
->glCtx
);
248 _vbo_DestroyContext( &radeon
->glCtx
);
249 _swrast_DestroyContext( &radeon
->glCtx
);
252 /* free the Mesa context data */
253 _mesa_free_context_data(&radeon
->glCtx
);
255 /* free the option cache */
256 driDestroyOptionCache(&radeon
->optionCache
);
258 rcommonDestroyCmdBuf(radeon
);
260 radeon_destroy_atom_list(radeon
);
262 #ifdef RADEON_BO_TRACK
263 track
= fopen("/tmp/tracklog", "w");
265 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
272 /* Force the context `c' to be unbound from its buffer.
274 GLboolean
radeonUnbindContext(__DRIcontext
* driContextPriv
)
276 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
278 if (RADEON_DEBUG
& RADEON_DRI
)
279 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,
282 /* Unset current context and dispath table */
283 _mesa_make_current(NULL
, NULL
, NULL
);
290 radeon_bits_per_pixel(const struct radeon_renderbuffer
*rb
)
292 return _mesa_get_format_bytes(rb
->base
.Base
.Format
) * 8;
296 * Check if drawable has been invalidated by dri2InvalidateDrawable().
297 * Update renderbuffers if so. This prevents a client from accessing
298 * a backbuffer that has a swap pending but not yet completed.
300 * See intel_prepare_render for equivalent code in intel driver.
303 void radeon_prepare_render(radeonContextPtr radeon
)
305 __DRIcontext
*driContext
= radeon
->dri
.context
;
306 __DRIdrawable
*drawable
;
309 screen
= driContext
->driScreenPriv
;
310 if (!screen
->dri2
.loader
)
313 drawable
= driContext
->driDrawablePriv
;
314 if (drawable
->dri2
.stamp
!= driContext
->dri2
.draw_stamp
) {
315 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
316 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
318 /* Intel driver does the equivalent of this, no clue if it is needed:*/
319 radeon_draw_buffer(&radeon
->glCtx
, radeon
->glCtx
.DrawBuffer
);
321 driContext
->dri2
.draw_stamp
= drawable
->dri2
.stamp
;
324 drawable
= driContext
->driReadablePriv
;
325 if (drawable
->dri2
.stamp
!= driContext
->dri2
.read_stamp
) {
326 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
327 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
328 driContext
->dri2
.read_stamp
= drawable
->dri2
.stamp
;
331 /* If we're currently rendering to the front buffer, the rendering
332 * that will happen next will probably dirty the front buffer. So
333 * mark it as dirty here.
335 if (radeon
->is_front_buffer_rendering
)
336 radeon
->front_buffer_dirty
= GL_TRUE
;
340 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
,
341 GLboolean front_only
)
343 unsigned int attachments
[10];
344 __DRIbuffer
*buffers
= NULL
;
346 struct radeon_renderbuffer
*rb
;
348 struct radeon_framebuffer
*draw
;
349 radeonContextPtr radeon
;
351 struct radeon_bo
*depth_bo
= NULL
, *bo
;
353 if (RADEON_DEBUG
& RADEON_DRI
)
354 fprintf(stderr
, "enter %s, drawable %p\n", __func__
, drawable
);
356 draw
= drawable
->driverPrivate
;
357 screen
= context
->driScreenPriv
;
358 radeon
= (radeonContextPtr
) context
->driverPrivate
;
360 /* Set this up front, so that in case our buffers get invalidated
361 * while we're getting new buffers, we don't clobber the stamp and
362 * thus ignore the invalidate. */
363 drawable
->lastStamp
= drawable
->dri2
.stamp
;
365 if (screen
->dri2
.loader
366 && (screen
->dri2
.loader
->base
.version
> 2)
367 && (screen
->dri2
.loader
->getBuffersWithFormat
!= NULL
)) {
368 struct radeon_renderbuffer
*depth_rb
;
369 struct radeon_renderbuffer
*stencil_rb
;
372 if ((front_only
|| radeon
->is_front_buffer_rendering
||
373 radeon
->is_front_buffer_reading
||
375 && draw
->color_rb
[0]) {
376 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
377 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[0]);
381 if (draw
->color_rb
[1]) {
382 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
383 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[1]);
386 depth_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
387 stencil_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
389 if ((depth_rb
!= NULL
) && (stencil_rb
!= NULL
)) {
390 attachments
[i
++] = __DRI_BUFFER_DEPTH_STENCIL
;
391 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
392 } else if (depth_rb
!= NULL
) {
393 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
394 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
395 } else if (stencil_rb
!= NULL
) {
396 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
397 attachments
[i
++] = radeon_bits_per_pixel(stencil_rb
);
401 buffers
= (*screen
->dri2
.loader
->getBuffersWithFormat
)(drawable
,
406 drawable
->loaderPrivate
);
407 } else if (screen
->dri2
.loader
) {
409 if (draw
->color_rb
[0])
410 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
;
420 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
425 drawable
->loaderPrivate
);
431 for (i
= 0; i
< count
; i
++) {
432 switch (buffers
[i
].attachment
) {
433 case __DRI_BUFFER_FRONT_LEFT
:
434 rb
= draw
->color_rb
[0];
435 regname
= "dri2 front buffer";
437 case __DRI_BUFFER_FAKE_FRONT_LEFT
:
438 rb
= draw
->color_rb
[0];
439 regname
= "dri2 fake front buffer";
441 case __DRI_BUFFER_BACK_LEFT
:
442 rb
= draw
->color_rb
[1];
443 regname
= "dri2 back buffer";
445 case __DRI_BUFFER_DEPTH
:
446 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
447 regname
= "dri2 depth buffer";
449 case __DRI_BUFFER_DEPTH_STENCIL
:
450 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
451 regname
= "dri2 depth / stencil buffer";
453 case __DRI_BUFFER_STENCIL
:
454 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
455 regname
= "dri2 stencil buffer";
457 case __DRI_BUFFER_ACCUM
:
460 "unhandled buffer attach event, attacment type %d\n",
461 buffers
[i
].attachment
);
469 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
470 if (name
== buffers
[i
].name
)
474 if (RADEON_DEBUG
& RADEON_DRI
)
476 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
477 regname
, buffers
[i
].name
, buffers
[i
].attachment
,
478 buffers
[i
].cpp
, buffers
[i
].pitch
);
480 rb
->cpp
= buffers
[i
].cpp
;
481 rb
->pitch
= buffers
[i
].pitch
;
482 rb
->base
.Base
.Width
= drawable
->w
;
483 rb
->base
.Base
.Height
= drawable
->h
;
486 if (buffers
[i
].attachment
== __DRI_BUFFER_STENCIL
&& depth_bo
) {
487 if (RADEON_DEBUG
& RADEON_DRI
)
488 fprintf(stderr
, "(reusing depth buffer as stencil)\n");
492 uint32_t tiling_flags
= 0, pitch
= 0;
495 bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
499 RADEON_GEM_DOMAIN_VRAM
,
503 fprintf(stderr
, "failed to attach %s %d\n",
504 regname
, buffers
[i
].name
);
508 ret
= radeon_bo_get_tiling(bo
, &tiling_flags
, &pitch
);
511 "failed to get tiling for %s %d\n",
512 regname
, buffers
[i
].name
);
517 if (tiling_flags
& RADEON_TILING_MACRO
)
518 bo
->flags
|= RADEON_BO_FLAGS_MACRO_TILE
;
519 if (tiling_flags
& RADEON_TILING_MICRO
)
520 bo
->flags
|= RADEON_BO_FLAGS_MICRO_TILE
;
524 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH
) {
525 if (draw
->base
.Visual
.depthBits
== 16)
530 radeon_renderbuffer_set_bo(rb
, bo
);
533 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH_STENCIL
) {
534 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
536 struct radeon_bo
*stencil_bo
= NULL
;
539 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
540 if (name
== buffers
[i
].name
)
545 radeon_bo_ref(stencil_bo
);
546 radeon_renderbuffer_set_bo(rb
, stencil_bo
);
547 radeon_bo_unref(stencil_bo
);
552 driUpdateFramebufferSize(&radeon
->glCtx
, drawable
);
555 /* Force the context `c' to be the current context and associate with it
558 GLboolean
radeonMakeCurrent(__DRIcontext
* driContextPriv
,
559 __DRIdrawable
* driDrawPriv
,
560 __DRIdrawable
* driReadPriv
)
562 radeonContextPtr radeon
;
563 GET_CURRENT_CONTEXT(curCtx
);
564 struct gl_framebuffer
*drfb
, *readfb
;
567 radeon
= (radeonContextPtr
)driContextPriv
->driverPrivate
;
570 /* According to the glXMakeCurrent() man page: "Pending commands to
571 * the previous context, if any, are flushed before it is released."
572 * But only flush if we're actually changing contexts.
575 if ((radeonContextPtr
)curCtx
&& (radeonContextPtr
)curCtx
!= radeon
) {
579 if (!driContextPriv
) {
580 if (RADEON_DEBUG
& RADEON_DRI
)
581 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
582 _mesa_make_current(NULL
, NULL
, NULL
);
586 if(driDrawPriv
== NULL
&& driReadPriv
== NULL
) {
587 drfb
= _mesa_create_framebuffer(&radeon
->glCtx
.Visual
);
591 drfb
= driDrawPriv
->driverPrivate
;
592 readfb
= driReadPriv
->driverPrivate
;
596 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
, GL_FALSE
);
597 if (driDrawPriv
!= driReadPriv
)
598 radeon_update_renderbuffers(driContextPriv
, driReadPriv
, GL_FALSE
);
599 _mesa_reference_renderbuffer(&radeon
->state
.color
.rb
,
600 &(radeon_get_renderbuffer(drfb
, BUFFER_BACK_LEFT
)->base
.Base
));
601 _mesa_reference_renderbuffer(&radeon
->state
.depth
.rb
,
602 &(radeon_get_renderbuffer(drfb
, BUFFER_DEPTH
)->base
.Base
));
604 if (RADEON_DEBUG
& RADEON_DRI
)
605 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__
, &radeon
->glCtx
, drfb
, readfb
);
608 driUpdateFramebufferSize(&radeon
->glCtx
, driDrawPriv
);
609 if (driReadPriv
!= driDrawPriv
)
610 driUpdateFramebufferSize(&radeon
->glCtx
, driReadPriv
);
612 _mesa_make_current(&radeon
->glCtx
, drfb
, readfb
);
613 if (driDrawPriv
== NULL
&& driReadPriv
== NULL
)
614 _mesa_reference_framebuffer(&drfb
, NULL
);
616 _mesa_update_state(&radeon
->glCtx
);
618 if (radeon
->glCtx
.DrawBuffer
== drfb
) {
619 if(driDrawPriv
!= NULL
) {
620 radeon_window_moved(radeon
);
623 radeon_draw_buffer(&radeon
->glCtx
, drfb
);
627 if (RADEON_DEBUG
& RADEON_DRI
)
628 fprintf(stderr
, "End %s\n", __FUNCTION__
);