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 "drivers/common/meta.h"
41 #include "main/context.h"
42 #include "main/framebuffer.h"
43 #include "main/renderbuffer.h"
44 #include "main/state.h"
45 #include "main/simple_list.h"
46 #include "swrast/swrast.h"
47 #include "swrast_setup/swrast_setup.h"
50 #define DRIVER_DATE "20090101"
53 int RADEON_DEBUG
= (0);
57 static const char* get_chip_family_name(int chip_family
)
60 case CHIP_FAMILY_R100
: return "R100";
61 case CHIP_FAMILY_RV100
: return "RV100";
62 case CHIP_FAMILY_RS100
: return "RS100";
63 case CHIP_FAMILY_RV200
: return "RV200";
64 case CHIP_FAMILY_RS200
: return "RS200";
65 case CHIP_FAMILY_R200
: return "R200";
66 case CHIP_FAMILY_RV250
: return "RV250";
67 case CHIP_FAMILY_RS300
: return "RS300";
68 case CHIP_FAMILY_RV280
: return "RV280";
69 case CHIP_FAMILY_R300
: return "R300";
70 case CHIP_FAMILY_R350
: return "R350";
71 case CHIP_FAMILY_RV350
: return "RV350";
72 case CHIP_FAMILY_RV380
: return "RV380";
73 case CHIP_FAMILY_R420
: return "R420";
74 case CHIP_FAMILY_RV410
: return "RV410";
75 case CHIP_FAMILY_RS400
: return "RS400";
76 case CHIP_FAMILY_RS600
: return "RS600";
77 case CHIP_FAMILY_RS690
: return "RS690";
78 case CHIP_FAMILY_RS740
: return "RS740";
79 case CHIP_FAMILY_RV515
: return "RV515";
80 case CHIP_FAMILY_R520
: return "R520";
81 case CHIP_FAMILY_RV530
: return "RV530";
82 case CHIP_FAMILY_R580
: return "R580";
83 case CHIP_FAMILY_RV560
: return "RV560";
84 case CHIP_FAMILY_RV570
: return "RV570";
85 case CHIP_FAMILY_R600
: return "R600";
86 case CHIP_FAMILY_RV610
: return "RV610";
87 case CHIP_FAMILY_RV630
: return "RV630";
88 case CHIP_FAMILY_RV670
: return "RV670";
89 case CHIP_FAMILY_RV620
: return "RV620";
90 case CHIP_FAMILY_RV635
: return "RV635";
91 case CHIP_FAMILY_RS780
: return "RS780";
92 case CHIP_FAMILY_RS880
: return "RS880";
93 case CHIP_FAMILY_RV770
: return "RV770";
94 case CHIP_FAMILY_RV730
: return "RV730";
95 case CHIP_FAMILY_RV710
: return "RV710";
96 case CHIP_FAMILY_RV740
: return "RV740";
97 case CHIP_FAMILY_CEDAR
: return "CEDAR";
98 case CHIP_FAMILY_REDWOOD
: return "REDWOOD";
99 case CHIP_FAMILY_JUNIPER
: return "JUNIPER";
100 case CHIP_FAMILY_CYPRESS
: return "CYPRESS";
101 case CHIP_FAMILY_HEMLOCK
: return "HEMLOCK";
102 case CHIP_FAMILY_PALM
: return "PALM";
103 default: return "unknown";
108 /* Return various strings for glGetString().
110 static const GLubyte
*radeonGetString(struct gl_context
* ctx
, GLenum name
)
112 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
113 static char buffer
[128];
117 if (IS_R600_CLASS(radeon
->radeonScreen
))
118 return (GLubyte
*) "Advanced Micro Devices, Inc.";
119 else if (IS_R300_CLASS(radeon
->radeonScreen
))
120 return (GLubyte
*) "DRI R300 Project";
122 return (GLubyte
*) "Tungsten Graphics, Inc.";
127 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
128 radeon
->radeonScreen
->AGPMode
;
129 const char* chipclass
;
130 char hardwarename
[32];
132 if (IS_R600_CLASS(radeon
->radeonScreen
))
134 else if (IS_R300_CLASS(radeon
->radeonScreen
))
136 else if (IS_R200_CLASS(radeon
->radeonScreen
))
141 sprintf(hardwarename
, "%s (%s %04X)",
143 get_chip_family_name(radeon
->radeonScreen
->chip_family
),
144 radeon
->radeonScreen
->device_id
);
146 offset
= driGetRendererString(buffer
, hardwarename
, DRIVER_DATE
,
149 if (IS_R600_CLASS(radeon
->radeonScreen
)) {
150 sprintf(&buffer
[offset
], " TCL");
151 } else if (IS_R300_CLASS(radeon
->radeonScreen
)) {
152 sprintf(&buffer
[offset
], " %sTCL",
153 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
156 sprintf(&buffer
[offset
], " %sTCL",
157 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
161 if (radeon
->radeonScreen
->driScreen
->dri2
.enabled
)
162 strcat(buffer
, " DRI2");
164 return (GLubyte
*) buffer
;
172 /* Initialize the driver's misc functions.
174 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
176 functions
->GetString
= radeonGetString
;
180 * Create and initialize all common fields of the context,
181 * including the Mesa context itself.
183 GLboolean
radeonInitContext(radeonContextPtr radeon
,
184 struct dd_function_table
* functions
,
185 const struct gl_config
* glVisual
,
186 __DRIcontext
* driContextPriv
,
187 void *sharedContextPrivate
)
189 __DRIscreen
*sPriv
= driContextPriv
->driScreenPriv
;
190 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
191 struct gl_context
* ctx
;
192 struct gl_context
* shareCtx
;
195 /* Fill in additional standard functions. */
196 radeonInitDriverFuncs(functions
);
198 radeon
->radeonScreen
= screen
;
199 /* Allocate and initialize the Mesa context */
200 if (sharedContextPrivate
)
201 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
204 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
205 functions
, (void *)radeon
);
210 driContextPriv
->driverPrivate
= radeon
;
212 meta_init_metaops(ctx
, &radeon
->meta
);
214 _mesa_meta_init(ctx
);
217 radeon
->dri
.context
= driContextPriv
;
218 radeon
->dri
.screen
= sPriv
;
219 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
220 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
221 radeon
->dri
.hwLockCount
= 0;
222 radeon
->dri
.fd
= sPriv
->fd
;
223 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
225 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
226 screen
->sarea_priv_offset
);
229 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
230 radeon
->iw
.irq_seq
= -1;
231 radeon
->irqsEmitted
= 0;
232 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
233 radeon
->radeonScreen
->irq
);
235 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
237 if (!radeon
->do_irqs
)
239 "IRQ's not enabled, falling back to %s: %d %d\n",
240 radeon
->do_usleeps
? "usleeps" : "busy waits",
241 fthrottle_mode
, radeon
->radeonScreen
->irq
);
243 radeon
->texture_depth
= driQueryOptioni (&radeon
->optionCache
,
245 if (radeon
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
246 radeon
->texture_depth
= ( glVisual
->rgbBits
> 16 ) ?
247 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
249 if (IS_R600_CLASS(radeon
->radeonScreen
)) {
250 radeon
->texture_row_align
= radeon
->radeonScreen
->group_bytes
;
251 radeon
->texture_rect_row_align
= radeon
->radeonScreen
->group_bytes
;
252 radeon
->texture_compressed_row_align
= radeon
->radeonScreen
->group_bytes
;
253 } else if (IS_R200_CLASS(radeon
->radeonScreen
) ||
254 IS_R100_CLASS(radeon
->radeonScreen
)) {
255 radeon
->texture_row_align
= 32;
256 radeon
->texture_rect_row_align
= 64;
257 radeon
->texture_compressed_row_align
= 32;
258 } else { /* R300 - not sure this is all correct */
259 int chip_family
= radeon
->radeonScreen
->chip_family
;
260 if (chip_family
== CHIP_FAMILY_RS600
||
261 chip_family
== CHIP_FAMILY_RS690
||
262 chip_family
== CHIP_FAMILY_RS740
)
263 radeon
->texture_row_align
= 64;
265 radeon
->texture_row_align
= 32;
266 radeon
->texture_rect_row_align
= 64;
267 radeon
->texture_compressed_row_align
= 32;
270 radeon_init_dma(radeon
);
278 * Destroy the command buffer and state atoms.
280 static void radeon_destroy_atom_list(radeonContextPtr radeon
)
282 struct radeon_state_atom
*atom
;
284 foreach(atom
, &radeon
->hw
.atomlist
) {
293 * Cleanup common context fields.
294 * Called by r200DestroyContext/r300DestroyContext
296 void radeonDestroyContext(__DRIcontext
*driContextPriv
)
298 #ifdef RADEON_BO_TRACK
301 GET_CURRENT_CONTEXT(ctx
);
302 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
303 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
307 _mesa_meta_free(radeon
->glCtx
);
309 if (radeon
== current
) {
310 _mesa_make_current(NULL
, NULL
, NULL
);
313 radeon_firevertices(radeon
);
314 if (!is_empty_list(&radeon
->dma
.reserved
)) {
315 rcommonFlushCmdBuf( radeon
, __FUNCTION__
);
318 radeonFreeDmaRegions(radeon
);
319 radeonReleaseArrays(radeon
->glCtx
, ~0);
320 meta_destroy_metaops(&radeon
->meta
);
321 if (radeon
->vtbl
.free_context
)
322 radeon
->vtbl
.free_context(radeon
->glCtx
);
323 _swsetup_DestroyContext( radeon
->glCtx
);
324 _tnl_DestroyContext( radeon
->glCtx
);
325 _vbo_DestroyContext( radeon
->glCtx
);
326 _swrast_DestroyContext( radeon
->glCtx
);
329 /* free the Mesa context */
330 _mesa_destroy_context(radeon
->glCtx
);
332 /* _mesa_destroy_context() might result in calls to functions that
333 * depend on the DriverCtx, so don't set it to NULL before.
335 * radeon->glCtx->DriverCtx = NULL;
337 /* free the option cache */
338 driDestroyOptionCache(&radeon
->optionCache
);
340 rcommonDestroyCmdBuf(radeon
);
342 radeon_destroy_atom_list(radeon
);
344 if (radeon
->state
.scissor
.pClipRects
) {
345 FREE(radeon
->state
.scissor
.pClipRects
);
346 radeon
->state
.scissor
.pClipRects
= 0;
348 #ifdef RADEON_BO_TRACK
349 track
= fopen("/tmp/tracklog", "w");
351 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
358 /* Force the context `c' to be unbound from its buffer.
360 GLboolean
radeonUnbindContext(__DRIcontext
* driContextPriv
)
362 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
364 if (RADEON_DEBUG
& RADEON_DRI
)
365 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,
368 /* Unset current context and dispath table */
369 _mesa_make_current(NULL
, NULL
, NULL
);
376 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
377 struct gl_framebuffer
*draw
)
379 /* if radeon->fake */
380 struct radeon_renderbuffer
*rb
;
382 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
384 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
385 radeon
->radeonScreen
->frontOffset
,
388 RADEON_GEM_DOMAIN_VRAM
,
391 rb
->cpp
= radeon
->radeonScreen
->cpp
;
392 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
394 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
396 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
397 radeon
->radeonScreen
->backOffset
,
400 RADEON_GEM_DOMAIN_VRAM
,
403 rb
->cpp
= radeon
->radeonScreen
->cpp
;
404 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
406 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
408 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
409 radeon
->radeonScreen
->depthOffset
,
412 RADEON_GEM_DOMAIN_VRAM
,
415 rb
->cpp
= radeon
->radeonScreen
->cpp
;
416 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
418 if ((rb
= (void *)draw
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
420 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
421 radeon
->radeonScreen
->depthOffset
,
424 RADEON_GEM_DOMAIN_VRAM
,
427 rb
->cpp
= radeon
->radeonScreen
->cpp
;
428 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
433 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
434 struct gl_framebuffer
*draw
)
436 int size
= 4096*4096*4;
437 /* if radeon->fake */
438 struct radeon_renderbuffer
*rb
;
440 if (radeon
->radeonScreen
->kernel_mm
) {
441 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
446 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
448 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
449 radeon
->radeonScreen
->frontOffset
+
450 radeon
->radeonScreen
->fbLocation
,
453 RADEON_GEM_DOMAIN_VRAM
,
456 rb
->cpp
= radeon
->radeonScreen
->cpp
;
457 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
459 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
461 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
462 radeon
->radeonScreen
->backOffset
+
463 radeon
->radeonScreen
->fbLocation
,
466 RADEON_GEM_DOMAIN_VRAM
,
469 rb
->cpp
= radeon
->radeonScreen
->cpp
;
470 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
472 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
474 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
475 radeon
->radeonScreen
->depthOffset
+
476 radeon
->radeonScreen
->fbLocation
,
479 RADEON_GEM_DOMAIN_VRAM
,
482 rb
->cpp
= radeon
->radeonScreen
->cpp
;
483 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
485 if ((rb
= (void *)draw
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
487 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
488 radeon
->radeonScreen
->depthOffset
+
489 radeon
->radeonScreen
->fbLocation
,
492 RADEON_GEM_DOMAIN_VRAM
,
495 rb
->cpp
= radeon
->radeonScreen
->cpp
;
496 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
501 radeon_bits_per_pixel(const struct radeon_renderbuffer
*rb
)
503 return _mesa_get_format_bytes(rb
->base
.Format
) * 8;
507 * Check if drawable has been invalidated by dri2InvalidateDrawable().
508 * Update renderbuffers if so. This prevents a client from accessing
509 * a backbuffer that has a swap pending but not yet completed.
511 * See intel_prepare_render for equivalent code in intel driver.
514 void radeon_prepare_render(radeonContextPtr radeon
)
516 __DRIcontext
*driContext
= radeon
->dri
.context
;
517 __DRIdrawable
*drawable
;
519 struct radeon_framebuffer
*draw
;
521 screen
= driContext
->driScreenPriv
;
522 if (!screen
->dri2
.loader
)
525 drawable
= driContext
->driDrawablePriv
;
526 if (drawable
->dri2
.stamp
!= driContext
->dri2
.draw_stamp
) {
527 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
528 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
530 /* Intel driver does the equivalent of this, no clue if it is needed:*/
531 draw
= drawable
->driverPrivate
;
532 radeon_draw_buffer(radeon
->glCtx
, &draw
->base
);
534 driContext
->dri2
.draw_stamp
= drawable
->dri2
.stamp
;
537 drawable
= driContext
->driReadablePriv
;
538 if (drawable
->dri2
.stamp
!= driContext
->dri2
.read_stamp
) {
539 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
540 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
541 driContext
->dri2
.read_stamp
= drawable
->dri2
.stamp
;
544 /* If we're currently rendering to the front buffer, the rendering
545 * that will happen next will probably dirty the front buffer. So
546 * mark it as dirty here.
548 if (radeon
->is_front_buffer_rendering
)
549 radeon
->front_buffer_dirty
= GL_TRUE
;
553 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
,
554 GLboolean front_only
)
556 unsigned int attachments
[10];
557 __DRIbuffer
*buffers
= NULL
;
559 struct radeon_renderbuffer
*rb
;
561 struct radeon_framebuffer
*draw
;
562 radeonContextPtr radeon
;
564 struct radeon_bo
*depth_bo
= NULL
, *bo
;
566 if (RADEON_DEBUG
& RADEON_DRI
)
567 fprintf(stderr
, "enter %s, drawable %p\n", __func__
, drawable
);
569 draw
= drawable
->driverPrivate
;
570 screen
= context
->driScreenPriv
;
571 radeon
= (radeonContextPtr
) context
->driverPrivate
;
573 /* Set this up front, so that in case our buffers get invalidated
574 * while we're getting new buffers, we don't clobber the stamp and
575 * thus ignore the invalidate. */
576 drawable
->lastStamp
= drawable
->dri2
.stamp
;
578 if (screen
->dri2
.loader
579 && (screen
->dri2
.loader
->base
.version
> 2)
580 && (screen
->dri2
.loader
->getBuffersWithFormat
!= NULL
)) {
581 struct radeon_renderbuffer
*depth_rb
;
582 struct radeon_renderbuffer
*stencil_rb
;
585 if ((front_only
|| radeon
->is_front_buffer_rendering
||
586 radeon
->is_front_buffer_reading
||
588 && draw
->color_rb
[0]) {
589 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
590 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[0]);
594 if (draw
->color_rb
[1]) {
595 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
596 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[1]);
599 depth_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
600 stencil_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
602 if ((depth_rb
!= NULL
) && (stencil_rb
!= NULL
)) {
603 attachments
[i
++] = __DRI_BUFFER_DEPTH_STENCIL
;
604 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
605 } else if (depth_rb
!= NULL
) {
606 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
607 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
608 } else if (stencil_rb
!= NULL
) {
609 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
610 attachments
[i
++] = radeon_bits_per_pixel(stencil_rb
);
614 buffers
= (*screen
->dri2
.loader
->getBuffersWithFormat
)(drawable
,
619 drawable
->loaderPrivate
);
620 } else if (screen
->dri2
.loader
) {
622 if (draw
->color_rb
[0])
623 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
625 if (draw
->color_rb
[1])
626 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
627 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
))
628 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
629 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
))
630 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
633 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
638 drawable
->loaderPrivate
);
644 /* set one cliprect to cover the whole drawable */
649 drawable
->numClipRects
= 1;
650 drawable
->pClipRects
[0].x1
= 0;
651 drawable
->pClipRects
[0].y1
= 0;
652 drawable
->pClipRects
[0].x2
= drawable
->w
;
653 drawable
->pClipRects
[0].y2
= drawable
->h
;
654 drawable
->numBackClipRects
= 1;
655 drawable
->pBackClipRects
[0].x1
= 0;
656 drawable
->pBackClipRects
[0].y1
= 0;
657 drawable
->pBackClipRects
[0].x2
= drawable
->w
;
658 drawable
->pBackClipRects
[0].y2
= drawable
->h
;
659 for (i
= 0; i
< count
; i
++) {
660 switch (buffers
[i
].attachment
) {
661 case __DRI_BUFFER_FRONT_LEFT
:
662 rb
= draw
->color_rb
[0];
663 regname
= "dri2 front buffer";
665 case __DRI_BUFFER_FAKE_FRONT_LEFT
:
666 rb
= draw
->color_rb
[0];
667 regname
= "dri2 fake front buffer";
669 case __DRI_BUFFER_BACK_LEFT
:
670 rb
= draw
->color_rb
[1];
671 regname
= "dri2 back buffer";
673 case __DRI_BUFFER_DEPTH
:
674 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
675 regname
= "dri2 depth buffer";
677 case __DRI_BUFFER_DEPTH_STENCIL
:
678 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
679 regname
= "dri2 depth / stencil buffer";
681 case __DRI_BUFFER_STENCIL
:
682 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
683 regname
= "dri2 stencil buffer";
685 case __DRI_BUFFER_ACCUM
:
688 "unhandled buffer attach event, attacment type %d\n",
689 buffers
[i
].attachment
);
697 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
698 if (name
== buffers
[i
].name
)
702 if (RADEON_DEBUG
& RADEON_DRI
)
704 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
705 regname
, buffers
[i
].name
, buffers
[i
].attachment
,
706 buffers
[i
].cpp
, buffers
[i
].pitch
);
708 rb
->cpp
= buffers
[i
].cpp
;
709 rb
->pitch
= buffers
[i
].pitch
;
710 rb
->base
.Width
= drawable
->w
;
711 rb
->base
.Height
= drawable
->h
;
715 rb
->tile_config
= radeon
->radeonScreen
->tile_config
;
716 rb
->group_bytes
= radeon
->radeonScreen
->group_bytes
;
717 rb
->num_channels
= radeon
->radeonScreen
->num_channels
;
718 rb
->num_banks
= radeon
->radeonScreen
->num_banks
;
719 rb
->r7xx_bank_op
= radeon
->radeonScreen
->r7xx_bank_op
;
721 if (buffers
[i
].attachment
== __DRI_BUFFER_STENCIL
&& depth_bo
) {
722 if (RADEON_DEBUG
& RADEON_DRI
)
723 fprintf(stderr
, "(reusing depth buffer as stencil)\n");
727 uint32_t tiling_flags
= 0, pitch
= 0;
730 bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
734 RADEON_GEM_DOMAIN_VRAM
,
738 fprintf(stderr
, "failed to attach %s %d\n",
739 regname
, buffers
[i
].name
);
743 ret
= radeon_bo_get_tiling(bo
, &tiling_flags
, &pitch
);
744 if (tiling_flags
& RADEON_TILING_MACRO
)
745 bo
->flags
|= RADEON_BO_FLAGS_MACRO_TILE
;
746 if (tiling_flags
& RADEON_TILING_MICRO
)
747 bo
->flags
|= RADEON_BO_FLAGS_MICRO_TILE
;
751 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH
) {
752 if (draw
->base
.Visual
.depthBits
== 16)
757 radeon_renderbuffer_set_bo(rb
, bo
);
760 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH_STENCIL
) {
761 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
763 struct radeon_bo
*stencil_bo
= NULL
;
766 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
767 if (name
== buffers
[i
].name
)
772 radeon_bo_ref(stencil_bo
);
773 radeon_renderbuffer_set_bo(rb
, stencil_bo
);
774 radeon_bo_unref(stencil_bo
);
779 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
782 /* Force the context `c' to be the current context and associate with it
785 GLboolean
radeonMakeCurrent(__DRIcontext
* driContextPriv
,
786 __DRIdrawable
* driDrawPriv
,
787 __DRIdrawable
* driReadPriv
)
789 radeonContextPtr radeon
;
790 struct radeon_framebuffer
*rdrfb
;
791 struct gl_framebuffer
*drfb
, *readfb
;
793 if (!driContextPriv
) {
794 if (RADEON_DEBUG
& RADEON_DRI
)
795 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
796 _mesa_make_current(NULL
, NULL
, NULL
);
800 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
802 if(driDrawPriv
== NULL
&& driReadPriv
== NULL
) {
803 drfb
= _mesa_create_framebuffer(&radeon
->glCtx
->Visual
);
807 drfb
= driDrawPriv
->driverPrivate
;
808 readfb
= driReadPriv
->driverPrivate
;
811 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
813 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
, GL_FALSE
);
814 if (driDrawPriv
!= driReadPriv
)
815 radeon_update_renderbuffers(driContextPriv
, driReadPriv
, GL_FALSE
);
816 _mesa_reference_renderbuffer(&radeon
->state
.color
.rb
,
817 &(radeon_get_renderbuffer(drfb
, BUFFER_BACK_LEFT
)->base
));
818 _mesa_reference_renderbuffer(&radeon
->state
.depth
.rb
,
819 &(radeon_get_renderbuffer(drfb
, BUFFER_DEPTH
)->base
));
821 radeon_make_renderbuffer_current(radeon
, drfb
);
824 if (RADEON_DEBUG
& RADEON_DRI
)
825 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__
, radeon
->glCtx
, drfb
, readfb
);
828 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
829 if (driReadPriv
!= driDrawPriv
)
830 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
832 _mesa_make_current(radeon
->glCtx
, drfb
, readfb
);
833 if (driDrawPriv
== NULL
&& driReadPriv
== NULL
)
834 _mesa_reference_framebuffer(&drfb
, NULL
);
836 _mesa_update_state(radeon
->glCtx
);
838 if (radeon
->glCtx
->DrawBuffer
== drfb
) {
839 if(driDrawPriv
!= NULL
) {
840 rdrfb
= (struct radeon_framebuffer
*)drfb
;
841 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
843 driDrawPriv
->vblFlags
=
844 (radeon
->radeonScreen
->irq
!= 0)
845 ? driGetDefaultVBlankFlags(&radeon
->
847 : VBLANK_FLAG_NO_IRQ
;
849 driDrawableInitVBlank(driDrawPriv
);
850 rdrfb
->vbl_waited
= driDrawPriv
->vblSeq
;
852 for (i
= 0; i
< 2; i
++) {
853 if (rdrfb
->color_rb
[i
])
854 rdrfb
->color_rb
[i
]->vbl_pending
= driDrawPriv
->vblSeq
;
857 radeon_window_moved(radeon
);
860 radeon_draw_buffer(radeon
->glCtx
, drfb
);
864 if (RADEON_DEBUG
& RADEON_DRI
)
865 fprintf(stderr
, "End %s\n", __FUNCTION__
);