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 "util/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
->driContext
= driContextPriv
;
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 radeon
->texture_depth
= driQueryOptioni (&radeon
->optionCache
,
184 if (radeon
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
185 radeon
->texture_depth
= (glVisual
== NULL
|| glVisual
->rgbBits
> 16) ?
186 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
188 radeon
->texture_row_align
= 32;
189 radeon
->texture_rect_row_align
= 64;
190 radeon
->texture_compressed_row_align
= 32;
192 radeon_init_dma(radeon
);
194 /* _mesa_initialize_context calls _mesa_init_queryobj which
195 * initializes all of the counter sizes to 64. The counters on r100
196 * and r200 are only 32-bits for occlusion queries. Those are the
197 * only counters, so set the other sizes to zero.
199 radeon
->glCtx
.Const
.QueryCounterBits
.SamplesPassed
= 32;
201 radeon
->glCtx
.Const
.QueryCounterBits
.TimeElapsed
= 0;
202 radeon
->glCtx
.Const
.QueryCounterBits
.Timestamp
= 0;
203 radeon
->glCtx
.Const
.QueryCounterBits
.PrimitivesGenerated
= 0;
204 radeon
->glCtx
.Const
.QueryCounterBits
.PrimitivesWritten
= 0;
205 radeon
->glCtx
.Const
.QueryCounterBits
.VerticesSubmitted
= 0;
206 radeon
->glCtx
.Const
.QueryCounterBits
.PrimitivesSubmitted
= 0;
207 radeon
->glCtx
.Const
.QueryCounterBits
.VsInvocations
= 0;
208 radeon
->glCtx
.Const
.QueryCounterBits
.TessPatches
= 0;
209 radeon
->glCtx
.Const
.QueryCounterBits
.TessInvocations
= 0;
210 radeon
->glCtx
.Const
.QueryCounterBits
.GsInvocations
= 0;
211 radeon
->glCtx
.Const
.QueryCounterBits
.GsPrimitives
= 0;
212 radeon
->glCtx
.Const
.QueryCounterBits
.FsInvocations
= 0;
213 radeon
->glCtx
.Const
.QueryCounterBits
.ComputeInvocations
= 0;
214 radeon
->glCtx
.Const
.QueryCounterBits
.ClInPrimitives
= 0;
215 radeon
->glCtx
.Const
.QueryCounterBits
.ClOutPrimitives
= 0;
223 * Destroy the command buffer and state atoms.
225 static void radeon_destroy_atom_list(radeonContextPtr radeon
)
227 struct radeon_state_atom
*atom
;
229 foreach(atom
, &radeon
->hw
.atomlist
) {
237 * Cleanup common context fields.
238 * Called by r200DestroyContext
240 void radeonDestroyContext(__DRIcontext
*driContextPriv
)
242 #ifdef RADEON_BO_TRACK
245 GET_CURRENT_CONTEXT(ctx
);
246 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
247 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
251 _mesa_meta_free(&radeon
->glCtx
);
253 if (radeon
== current
) {
254 _mesa_make_current(NULL
, NULL
, NULL
);
257 radeon_firevertices(radeon
);
258 if (!is_empty_list(&radeon
->dma
.reserved
)) {
259 rcommonFlushCmdBuf( radeon
, __func__
);
262 radeonFreeDmaRegions(radeon
);
263 radeonReleaseArrays(&radeon
->glCtx
, ~0);
264 if (radeon
->vtbl
.free_context
)
265 radeon
->vtbl
.free_context(&radeon
->glCtx
);
266 _swsetup_DestroyContext( &radeon
->glCtx
);
267 _tnl_DestroyContext( &radeon
->glCtx
);
268 _vbo_DestroyContext( &radeon
->glCtx
);
269 _swrast_DestroyContext( &radeon
->glCtx
);
272 /* free the Mesa context data */
273 _mesa_free_context_data(&radeon
->glCtx
);
275 /* free the option cache */
276 driDestroyOptionCache(&radeon
->optionCache
);
278 rcommonDestroyCmdBuf(radeon
);
280 radeon_destroy_atom_list(radeon
);
282 #ifdef RADEON_BO_TRACK
283 track
= fopen("/tmp/tracklog", "w");
285 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
292 /* Force the context `c' to be unbound from its buffer.
294 GLboolean
radeonUnbindContext(__DRIcontext
* driContextPriv
)
296 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
298 if (RADEON_DEBUG
& RADEON_DRI
)
299 fprintf(stderr
, "%s ctx %p\n", __func__
,
302 /* Unset current context and dispath table */
303 _mesa_make_current(NULL
, NULL
, NULL
);
310 radeon_bits_per_pixel(const struct radeon_renderbuffer
*rb
)
312 return _mesa_get_format_bytes(rb
->base
.Base
.Format
) * 8;
316 * Check if drawable has been invalidated by dri2InvalidateDrawable().
317 * Update renderbuffers if so. This prevents a client from accessing
318 * a backbuffer that has a swap pending but not yet completed.
320 * See intel_prepare_render for equivalent code in intel driver.
323 void radeon_prepare_render(radeonContextPtr radeon
)
325 __DRIcontext
*driContext
= radeon
->driContext
;
326 __DRIdrawable
*drawable
;
329 screen
= driContext
->driScreenPriv
;
330 if (!screen
->dri2
.loader
)
333 drawable
= driContext
->driDrawablePriv
;
334 if (drawable
->dri2
.stamp
!= driContext
->dri2
.draw_stamp
) {
335 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
336 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
338 /* Intel driver does the equivalent of this, no clue if it is needed:*/
339 radeon_draw_buffer(&radeon
->glCtx
, radeon
->glCtx
.DrawBuffer
);
341 driContext
->dri2
.draw_stamp
= drawable
->dri2
.stamp
;
344 drawable
= driContext
->driReadablePriv
;
345 if (drawable
->dri2
.stamp
!= driContext
->dri2
.read_stamp
) {
346 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
347 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
348 driContext
->dri2
.read_stamp
= drawable
->dri2
.stamp
;
351 /* If we're currently rendering to the front buffer, the rendering
352 * that will happen next will probably dirty the front buffer. So
353 * mark it as dirty here.
355 if (_mesa_is_front_buffer_drawing(radeon
->glCtx
.DrawBuffer
))
356 radeon
->front_buffer_dirty
= GL_TRUE
;
360 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
,
361 GLboolean front_only
)
363 unsigned int attachments
[10];
364 __DRIbuffer
*buffers
= NULL
;
366 struct radeon_renderbuffer
*rb
;
368 struct radeon_framebuffer
*draw
;
369 radeonContextPtr radeon
;
371 struct radeon_bo
*depth_bo
= NULL
, *bo
;
373 if (RADEON_DEBUG
& RADEON_DRI
)
374 fprintf(stderr
, "enter %s, drawable %p\n", __func__
, drawable
);
376 draw
= drawable
->driverPrivate
;
377 screen
= context
->driScreenPriv
;
378 radeon
= (radeonContextPtr
) context
->driverPrivate
;
380 /* Set this up front, so that in case our buffers get invalidated
381 * while we're getting new buffers, we don't clobber the stamp and
382 * thus ignore the invalidate. */
383 drawable
->lastStamp
= drawable
->dri2
.stamp
;
385 if (screen
->dri2
.loader
386 && (screen
->dri2
.loader
->base
.version
> 2)
387 && (screen
->dri2
.loader
->getBuffersWithFormat
!= NULL
)) {
388 struct radeon_renderbuffer
*depth_rb
;
389 struct radeon_renderbuffer
*stencil_rb
;
392 if ((front_only
|| _mesa_is_front_buffer_drawing(&draw
->base
) ||
393 _mesa_is_front_buffer_reading(&draw
->base
) ||
395 && draw
->color_rb
[0]) {
396 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
397 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[0]);
401 if (draw
->color_rb
[1]) {
402 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
403 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[1]);
406 depth_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
407 stencil_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
409 if ((depth_rb
!= NULL
) && (stencil_rb
!= NULL
)) {
410 attachments
[i
++] = __DRI_BUFFER_DEPTH_STENCIL
;
411 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
412 } else if (depth_rb
!= NULL
) {
413 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
414 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
415 } else if (stencil_rb
!= NULL
) {
416 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
417 attachments
[i
++] = radeon_bits_per_pixel(stencil_rb
);
421 buffers
= screen
->dri2
.loader
->getBuffersWithFormat(drawable
,
426 drawable
->loaderPrivate
);
427 } else if (screen
->dri2
.loader
) {
429 if (draw
->color_rb
[0])
430 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
;
440 buffers
= screen
->dri2
.loader
->getBuffers(drawable
,
445 drawable
->loaderPrivate
);
451 for (i
= 0; i
< count
; i
++) {
452 switch (buffers
[i
].attachment
) {
453 case __DRI_BUFFER_FRONT_LEFT
:
454 rb
= draw
->color_rb
[0];
455 regname
= "dri2 front buffer";
457 case __DRI_BUFFER_FAKE_FRONT_LEFT
:
458 rb
= draw
->color_rb
[0];
459 regname
= "dri2 fake front buffer";
461 case __DRI_BUFFER_BACK_LEFT
:
462 rb
= draw
->color_rb
[1];
463 regname
= "dri2 back buffer";
465 case __DRI_BUFFER_DEPTH
:
466 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
467 regname
= "dri2 depth buffer";
469 case __DRI_BUFFER_DEPTH_STENCIL
:
470 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
471 regname
= "dri2 depth / stencil buffer";
473 case __DRI_BUFFER_STENCIL
:
474 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
475 regname
= "dri2 stencil buffer";
477 case __DRI_BUFFER_ACCUM
:
480 "unhandled buffer attach event, attacment type %d\n",
481 buffers
[i
].attachment
);
489 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
490 if (name
== buffers
[i
].name
)
494 if (RADEON_DEBUG
& RADEON_DRI
)
496 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
497 regname
, buffers
[i
].name
, buffers
[i
].attachment
,
498 buffers
[i
].cpp
, buffers
[i
].pitch
);
500 rb
->cpp
= buffers
[i
].cpp
;
501 rb
->pitch
= buffers
[i
].pitch
;
502 rb
->base
.Base
.Width
= drawable
->w
;
503 rb
->base
.Base
.Height
= drawable
->h
;
506 if (buffers
[i
].attachment
== __DRI_BUFFER_STENCIL
&& depth_bo
) {
507 if (RADEON_DEBUG
& RADEON_DRI
)
508 fprintf(stderr
, "(reusing depth buffer as stencil)\n");
512 uint32_t tiling_flags
= 0, pitch
= 0;
515 bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
519 RADEON_GEM_DOMAIN_VRAM
,
523 fprintf(stderr
, "failed to attach %s %d\n",
524 regname
, buffers
[i
].name
);
528 ret
= radeon_bo_get_tiling(bo
, &tiling_flags
, &pitch
);
531 "failed to get tiling for %s %d\n",
532 regname
, buffers
[i
].name
);
537 if (tiling_flags
& RADEON_TILING_MACRO
)
538 bo
->flags
|= RADEON_BO_FLAGS_MACRO_TILE
;
539 if (tiling_flags
& RADEON_TILING_MICRO
)
540 bo
->flags
|= RADEON_BO_FLAGS_MICRO_TILE
;
544 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH
) {
545 if (draw
->base
.Visual
.depthBits
== 16)
550 radeon_renderbuffer_set_bo(rb
, bo
);
553 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH_STENCIL
) {
554 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
556 struct radeon_bo
*stencil_bo
= NULL
;
559 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
560 if (name
== buffers
[i
].name
)
565 radeon_bo_ref(stencil_bo
);
566 radeon_renderbuffer_set_bo(rb
, stencil_bo
);
567 radeon_bo_unref(stencil_bo
);
572 driUpdateFramebufferSize(&radeon
->glCtx
, drawable
);
575 /* Force the context `c' to be the current context and associate with it
578 GLboolean
radeonMakeCurrent(__DRIcontext
* driContextPriv
,
579 __DRIdrawable
* driDrawPriv
,
580 __DRIdrawable
* driReadPriv
)
582 radeonContextPtr radeon
;
583 GET_CURRENT_CONTEXT(curCtx
);
584 struct gl_framebuffer
*drfb
, *readfb
;
587 radeon
= (radeonContextPtr
)driContextPriv
->driverPrivate
;
590 /* According to the glXMakeCurrent() man page: "Pending commands to
591 * the previous context, if any, are flushed before it is released."
592 * But only flush if we're actually changing contexts.
595 if ((radeonContextPtr
)curCtx
&& (radeonContextPtr
)curCtx
!= radeon
) {
599 if (!driContextPriv
) {
600 if (RADEON_DEBUG
& RADEON_DRI
)
601 fprintf(stderr
, "%s ctx is null\n", __func__
);
602 _mesa_make_current(NULL
, NULL
, NULL
);
606 if(driDrawPriv
== NULL
&& driReadPriv
== NULL
) {
607 drfb
= _mesa_create_framebuffer(&radeon
->glCtx
.Visual
);
611 drfb
= driDrawPriv
->driverPrivate
;
612 readfb
= driReadPriv
->driverPrivate
;
616 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
, GL_FALSE
);
617 if (driDrawPriv
!= driReadPriv
)
618 radeon_update_renderbuffers(driContextPriv
, driReadPriv
, GL_FALSE
);
619 _mesa_reference_renderbuffer(&radeon
->state
.color
.rb
,
620 &(radeon_get_renderbuffer(drfb
, BUFFER_BACK_LEFT
)->base
.Base
));
621 _mesa_reference_renderbuffer(&radeon
->state
.depth
.rb
,
622 &(radeon_get_renderbuffer(drfb
, BUFFER_DEPTH
)->base
.Base
));
624 if (RADEON_DEBUG
& RADEON_DRI
)
625 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __func__
, &radeon
->glCtx
, drfb
, readfb
);
628 driUpdateFramebufferSize(&radeon
->glCtx
, driDrawPriv
);
629 if (driReadPriv
!= driDrawPriv
)
630 driUpdateFramebufferSize(&radeon
->glCtx
, driReadPriv
);
632 _mesa_make_current(&radeon
->glCtx
, drfb
, readfb
);
633 if (driDrawPriv
== NULL
&& driReadPriv
== NULL
)
634 _mesa_reference_framebuffer(&drfb
, NULL
);
636 _mesa_update_state(&radeon
->glCtx
);
638 if (radeon
->glCtx
.DrawBuffer
== drfb
) {
639 if(driDrawPriv
!= NULL
) {
640 radeon_window_moved(radeon
);
643 radeon_draw_buffer(&radeon
->glCtx
, drfb
);
647 if (RADEON_DEBUG
& RADEON_DRI
)
648 fprintf(stderr
, "End %s\n", __func__
);