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/renderbuffer.h"
43 #include "main/state.h"
44 #include "main/simple_list.h"
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
49 #define DRIVER_DATE "20090101"
52 int RADEON_DEBUG
= (0);
56 static const char* get_chip_family_name(int chip_family
)
59 case CHIP_FAMILY_R100
: return "R100";
60 case CHIP_FAMILY_RV100
: return "RV100";
61 case CHIP_FAMILY_RS100
: return "RS100";
62 case CHIP_FAMILY_RV200
: return "RV200";
63 case CHIP_FAMILY_RS200
: return "RS200";
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";
68 case CHIP_FAMILY_R300
: return "R300";
69 case CHIP_FAMILY_R350
: return "R350";
70 case CHIP_FAMILY_RV350
: return "RV350";
71 case CHIP_FAMILY_RV380
: return "RV380";
72 case CHIP_FAMILY_R420
: return "R420";
73 case CHIP_FAMILY_RV410
: return "RV410";
74 case CHIP_FAMILY_RS400
: return "RS400";
75 case CHIP_FAMILY_RS600
: return "RS600";
76 case CHIP_FAMILY_RS690
: return "RS690";
77 case CHIP_FAMILY_RS740
: return "RS740";
78 case CHIP_FAMILY_RV515
: return "RV515";
79 case CHIP_FAMILY_R520
: return "R520";
80 case CHIP_FAMILY_RV530
: return "RV530";
81 case CHIP_FAMILY_R580
: return "R580";
82 case CHIP_FAMILY_RV560
: return "RV560";
83 case CHIP_FAMILY_RV570
: return "RV570";
84 case CHIP_FAMILY_R600
: return "R600";
85 case CHIP_FAMILY_RV610
: return "RV610";
86 case CHIP_FAMILY_RV630
: return "RV630";
87 case CHIP_FAMILY_RV670
: return "RV670";
88 case CHIP_FAMILY_RV620
: return "RV620";
89 case CHIP_FAMILY_RV635
: return "RV635";
90 case CHIP_FAMILY_RS780
: return "RS780";
91 case CHIP_FAMILY_RS880
: return "RS880";
92 case CHIP_FAMILY_RV770
: return "RV770";
93 case CHIP_FAMILY_RV730
: return "RV730";
94 case CHIP_FAMILY_RV710
: return "RV710";
95 case CHIP_FAMILY_RV740
: return "RV740";
96 case CHIP_FAMILY_CEDAR
: return "CEDAR";
97 case CHIP_FAMILY_REDWOOD
: return "REDWOOD";
98 case CHIP_FAMILY_JUNIPER
: return "JUNIPER";
99 case CHIP_FAMILY_CYPRESS
: return "CYPRESS";
100 case CHIP_FAMILY_HEMLOCK
: return "HEMLOCK";
101 default: return "unknown";
106 /* Return various strings for glGetString().
108 static const GLubyte
*radeonGetString(GLcontext
* ctx
, GLenum name
)
110 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
111 static char buffer
[128];
115 if (IS_R600_CLASS(radeon
->radeonScreen
))
116 return (GLubyte
*) "Advanced Micro Devices, Inc.";
117 else if (IS_R300_CLASS(radeon
->radeonScreen
))
118 return (GLubyte
*) "DRI R300 Project";
120 return (GLubyte
*) "Tungsten Graphics, Inc.";
125 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
126 radeon
->radeonScreen
->AGPMode
;
127 const char* chipclass
;
128 char hardwarename
[32];
130 if (IS_R600_CLASS(radeon
->radeonScreen
))
132 else if (IS_R300_CLASS(radeon
->radeonScreen
))
134 else if (IS_R200_CLASS(radeon
->radeonScreen
))
139 sprintf(hardwarename
, "%s (%s %04X)",
141 get_chip_family_name(radeon
->radeonScreen
->chip_family
),
142 radeon
->radeonScreen
->device_id
);
144 offset
= driGetRendererString(buffer
, hardwarename
, DRIVER_DATE
,
147 if (IS_R600_CLASS(radeon
->radeonScreen
)) {
148 sprintf(&buffer
[offset
], " TCL");
149 } else if (IS_R300_CLASS(radeon
->radeonScreen
)) {
150 sprintf(&buffer
[offset
], " %sTCL",
151 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
154 sprintf(&buffer
[offset
], " %sTCL",
155 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
159 if (radeon
->radeonScreen
->driScreen
->dri2
.enabled
)
160 strcat(buffer
, " DRI2");
162 return (GLubyte
*) buffer
;
170 /* Initialize the driver's misc functions.
172 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
174 functions
->GetString
= radeonGetString
;
178 * Create and initialize all common fields of the context,
179 * including the Mesa context itself.
181 GLboolean
radeonInitContext(radeonContextPtr radeon
,
182 struct dd_function_table
* functions
,
183 const __GLcontextModes
* glVisual
,
184 __DRIcontext
* driContextPriv
,
185 void *sharedContextPrivate
)
187 __DRIscreen
*sPriv
= driContextPriv
->driScreenPriv
;
188 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
193 /* Fill in additional standard functions. */
194 radeonInitDriverFuncs(functions
);
196 radeon
->radeonScreen
= screen
;
197 /* Allocate and initialize the Mesa context */
198 if (sharedContextPrivate
)
199 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
202 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
203 functions
, (void *)radeon
);
208 driContextPriv
->driverPrivate
= radeon
;
210 meta_init_metaops(ctx
, &radeon
->meta
);
212 _mesa_meta_init(ctx
);
215 radeon
->dri
.context
= driContextPriv
;
216 radeon
->dri
.screen
= sPriv
;
217 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
218 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
219 radeon
->dri
.hwLockCount
= 0;
220 radeon
->dri
.fd
= sPriv
->fd
;
221 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
223 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
224 screen
->sarea_priv_offset
);
227 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
228 radeon
->iw
.irq_seq
= -1;
229 radeon
->irqsEmitted
= 0;
230 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
231 radeon
->radeonScreen
->irq
);
233 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
235 if (!radeon
->do_irqs
)
237 "IRQ's not enabled, falling back to %s: %d %d\n",
238 radeon
->do_usleeps
? "usleeps" : "busy waits",
239 fthrottle_mode
, radeon
->radeonScreen
->irq
);
241 radeon
->texture_depth
= driQueryOptioni (&radeon
->optionCache
,
243 if (radeon
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
244 radeon
->texture_depth
= ( glVisual
->rgbBits
> 16 ) ?
245 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
247 if (IS_R600_CLASS(radeon
->radeonScreen
)) {
248 int chip_family
= radeon
->radeonScreen
->chip_family
;
249 if (chip_family
>= CHIP_FAMILY_CEDAR
) {
250 radeon
->texture_row_align
= 512;
251 radeon
->texture_rect_row_align
= 512;
252 radeon
->texture_compressed_row_align
= 512;
254 radeon
->texture_row_align
= 256;
255 radeon
->texture_rect_row_align
= 256;
256 radeon
->texture_compressed_row_align
= 256;
258 } else if (IS_R200_CLASS(radeon
->radeonScreen
) ||
259 IS_R100_CLASS(radeon
->radeonScreen
)) {
260 radeon
->texture_row_align
= 32;
261 radeon
->texture_rect_row_align
= 64;
262 radeon
->texture_compressed_row_align
= 32;
263 } else { /* R300 - not sure this is all correct */
264 int chip_family
= radeon
->radeonScreen
->chip_family
;
265 if (chip_family
== CHIP_FAMILY_RS600
||
266 chip_family
== CHIP_FAMILY_RS690
||
267 chip_family
== CHIP_FAMILY_RS740
)
268 radeon
->texture_row_align
= 64;
270 radeon
->texture_row_align
= 32;
271 radeon
->texture_rect_row_align
= 64;
272 radeon
->texture_compressed_row_align
= 32;
275 radeon_init_dma(radeon
);
283 * Destroy the command buffer and state atoms.
285 static void radeon_destroy_atom_list(radeonContextPtr radeon
)
287 struct radeon_state_atom
*atom
;
289 foreach(atom
, &radeon
->hw
.atomlist
) {
298 * Cleanup common context fields.
299 * Called by r200DestroyContext/r300DestroyContext
301 void radeonDestroyContext(__DRIcontext
*driContextPriv
)
303 #ifdef RADEON_BO_TRACK
306 GET_CURRENT_CONTEXT(ctx
);
307 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
308 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
312 _mesa_meta_free(radeon
->glCtx
);
314 if (radeon
== current
) {
315 _mesa_make_current(NULL
, NULL
, NULL
);
318 radeon_firevertices(radeon
);
319 if (!is_empty_list(&radeon
->dma
.reserved
)) {
320 rcommonFlushCmdBuf( radeon
, __FUNCTION__
);
323 radeonFreeDmaRegions(radeon
);
324 radeonReleaseArrays(radeon
->glCtx
, ~0);
325 meta_destroy_metaops(&radeon
->meta
);
326 if (radeon
->vtbl
.free_context
)
327 radeon
->vtbl
.free_context(radeon
->glCtx
);
328 _swsetup_DestroyContext( radeon
->glCtx
);
329 _tnl_DestroyContext( radeon
->glCtx
);
330 _vbo_DestroyContext( radeon
->glCtx
);
331 _swrast_DestroyContext( radeon
->glCtx
);
334 /* free the Mesa context */
335 _mesa_destroy_context(radeon
->glCtx
);
337 /* _mesa_destroy_context() might result in calls to functions that
338 * depend on the DriverCtx, so don't set it to NULL before.
340 * radeon->glCtx->DriverCtx = NULL;
342 /* free the option cache */
343 driDestroyOptionCache(&radeon
->optionCache
);
345 rcommonDestroyCmdBuf(radeon
);
347 radeon_destroy_atom_list(radeon
);
349 if (radeon
->state
.scissor
.pClipRects
) {
350 FREE(radeon
->state
.scissor
.pClipRects
);
351 radeon
->state
.scissor
.pClipRects
= 0;
353 #ifdef RADEON_BO_TRACK
354 track
= fopen("/tmp/tracklog", "w");
356 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
363 /* Force the context `c' to be unbound from its buffer.
365 GLboolean
radeonUnbindContext(__DRIcontext
* driContextPriv
)
367 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
369 if (RADEON_DEBUG
& RADEON_DRI
)
370 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,
373 /* Unset current context and dispath table */
374 _mesa_make_current(NULL
, NULL
, NULL
);
381 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
382 struct radeon_framebuffer
*draw
)
384 /* if radeon->fake */
385 struct radeon_renderbuffer
*rb
;
387 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
389 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
390 radeon
->radeonScreen
->frontOffset
,
393 RADEON_GEM_DOMAIN_VRAM
,
396 rb
->cpp
= radeon
->radeonScreen
->cpp
;
397 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
399 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
401 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
402 radeon
->radeonScreen
->backOffset
,
405 RADEON_GEM_DOMAIN_VRAM
,
408 rb
->cpp
= radeon
->radeonScreen
->cpp
;
409 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
411 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
413 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
414 radeon
->radeonScreen
->depthOffset
,
417 RADEON_GEM_DOMAIN_VRAM
,
420 rb
->cpp
= radeon
->radeonScreen
->cpp
;
421 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
423 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
425 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
426 radeon
->radeonScreen
->depthOffset
,
429 RADEON_GEM_DOMAIN_VRAM
,
432 rb
->cpp
= radeon
->radeonScreen
->cpp
;
433 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
438 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
439 struct radeon_framebuffer
*draw
)
441 int size
= 4096*4096*4;
442 /* if radeon->fake */
443 struct radeon_renderbuffer
*rb
;
445 if (radeon
->radeonScreen
->kernel_mm
) {
446 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
451 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
453 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
454 radeon
->radeonScreen
->frontOffset
+
455 radeon
->radeonScreen
->fbLocation
,
458 RADEON_GEM_DOMAIN_VRAM
,
461 rb
->cpp
= radeon
->radeonScreen
->cpp
;
462 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
464 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
466 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
467 radeon
->radeonScreen
->backOffset
+
468 radeon
->radeonScreen
->fbLocation
,
471 RADEON_GEM_DOMAIN_VRAM
,
474 rb
->cpp
= radeon
->radeonScreen
->cpp
;
475 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
477 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
479 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
480 radeon
->radeonScreen
->depthOffset
+
481 radeon
->radeonScreen
->fbLocation
,
484 RADEON_GEM_DOMAIN_VRAM
,
487 rb
->cpp
= radeon
->radeonScreen
->cpp
;
488 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
490 if ((rb
= (void *)draw
->base
.Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
492 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
493 radeon
->radeonScreen
->depthOffset
+
494 radeon
->radeonScreen
->fbLocation
,
497 RADEON_GEM_DOMAIN_VRAM
,
500 rb
->cpp
= radeon
->radeonScreen
->cpp
;
501 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
506 radeon_bits_per_pixel(const struct radeon_renderbuffer
*rb
)
508 return _mesa_get_format_bytes(rb
->base
.Format
) * 8;
512 * Check if drawable has been invalidated by dri2InvalidateDrawable().
513 * Update renderbuffers if so. This prevents a client from accessing
514 * a backbuffer that has a swap pending but not yet completed.
516 * See intel_prepare_render for equivalent code in intel driver.
519 void radeon_prepare_render(radeonContextPtr radeon
)
521 __DRIcontext
*driContext
= radeon
->dri
.context
;
522 __DRIdrawable
*drawable
;
525 screen
= driContext
->driScreenPriv
;
526 if (!screen
->dri2
.loader
)
529 drawable
= driContext
->driDrawablePriv
;
530 if (drawable
->dri2
.stamp
!= driContext
->dri2
.draw_stamp
) {
531 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
532 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
534 /* Intel driver does the equivalent of this, no clue if it is needed:
535 * radeon_draw_buffer(radeon->glCtx, &(drawable->driverPrivate)->base);
537 driContext
->dri2
.draw_stamp
= drawable
->dri2
.stamp
;
540 drawable
= driContext
->driReadablePriv
;
541 if (drawable
->dri2
.stamp
!= driContext
->dri2
.read_stamp
) {
542 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
543 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
544 driContext
->dri2
.read_stamp
= drawable
->dri2
.stamp
;
547 /* If we're currently rendering to the front buffer, the rendering
548 * that will happen next will probably dirty the front buffer. So
549 * mark it as dirty here.
551 if (radeon
->is_front_buffer_rendering
)
552 radeon
->front_buffer_dirty
= GL_TRUE
;
556 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
,
557 GLboolean front_only
)
559 unsigned int attachments
[10];
560 __DRIbuffer
*buffers
= NULL
;
562 struct radeon_renderbuffer
*rb
;
564 struct radeon_framebuffer
*draw
;
565 radeonContextPtr radeon
;
567 struct radeon_bo
*depth_bo
= NULL
, *bo
;
569 if (RADEON_DEBUG
& RADEON_DRI
)
570 fprintf(stderr
, "enter %s, drawable %p\n", __func__
, drawable
);
572 draw
= drawable
->driverPrivate
;
573 screen
= context
->driScreenPriv
;
574 radeon
= (radeonContextPtr
) context
->driverPrivate
;
576 /* Set this up front, so that in case our buffers get invalidated
577 * while we're getting new buffers, we don't clobber the stamp and
578 * thus ignore the invalidate. */
579 drawable
->lastStamp
= drawable
->dri2
.stamp
;
581 if (screen
->dri2
.loader
582 && (screen
->dri2
.loader
->base
.version
> 2)
583 && (screen
->dri2
.loader
->getBuffersWithFormat
!= NULL
)) {
584 struct radeon_renderbuffer
*depth_rb
;
585 struct radeon_renderbuffer
*stencil_rb
;
588 if ((front_only
|| radeon
->is_front_buffer_rendering
||
589 radeon
->is_front_buffer_reading
||
591 && draw
->color_rb
[0]) {
592 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
593 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[0]);
597 if (draw
->color_rb
[1]) {
598 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
599 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[1]);
602 depth_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
603 stencil_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
605 if ((depth_rb
!= NULL
) && (stencil_rb
!= NULL
)) {
606 attachments
[i
++] = __DRI_BUFFER_DEPTH_STENCIL
;
607 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
608 } else if (depth_rb
!= NULL
) {
609 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
610 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
611 } else if (stencil_rb
!= NULL
) {
612 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
613 attachments
[i
++] = radeon_bits_per_pixel(stencil_rb
);
617 buffers
= (*screen
->dri2
.loader
->getBuffersWithFormat
)(drawable
,
622 drawable
->loaderPrivate
);
623 } else if (screen
->dri2
.loader
) {
625 if (draw
->color_rb
[0])
626 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
628 if (draw
->color_rb
[1])
629 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
630 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
))
631 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
632 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
))
633 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
636 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
641 drawable
->loaderPrivate
);
647 /* set one cliprect to cover the whole drawable */
652 drawable
->numClipRects
= 1;
653 drawable
->pClipRects
[0].x1
= 0;
654 drawable
->pClipRects
[0].y1
= 0;
655 drawable
->pClipRects
[0].x2
= drawable
->w
;
656 drawable
->pClipRects
[0].y2
= drawable
->h
;
657 drawable
->numBackClipRects
= 1;
658 drawable
->pBackClipRects
[0].x1
= 0;
659 drawable
->pBackClipRects
[0].y1
= 0;
660 drawable
->pBackClipRects
[0].x2
= drawable
->w
;
661 drawable
->pBackClipRects
[0].y2
= drawable
->h
;
662 for (i
= 0; i
< count
; i
++) {
663 switch (buffers
[i
].attachment
) {
664 case __DRI_BUFFER_FRONT_LEFT
:
665 rb
= draw
->color_rb
[0];
666 regname
= "dri2 front buffer";
668 case __DRI_BUFFER_FAKE_FRONT_LEFT
:
669 rb
= draw
->color_rb
[0];
670 regname
= "dri2 fake front buffer";
672 case __DRI_BUFFER_BACK_LEFT
:
673 rb
= draw
->color_rb
[1];
674 regname
= "dri2 back buffer";
676 case __DRI_BUFFER_DEPTH
:
677 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
678 regname
= "dri2 depth buffer";
680 case __DRI_BUFFER_DEPTH_STENCIL
:
681 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
682 regname
= "dri2 depth / stencil buffer";
684 case __DRI_BUFFER_STENCIL
:
685 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
686 regname
= "dri2 stencil buffer";
688 case __DRI_BUFFER_ACCUM
:
691 "unhandled buffer attach event, attacment type %d\n",
692 buffers
[i
].attachment
);
700 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
701 if (name
== buffers
[i
].name
)
705 if (RADEON_DEBUG
& RADEON_DRI
)
707 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
708 regname
, buffers
[i
].name
, buffers
[i
].attachment
,
709 buffers
[i
].cpp
, buffers
[i
].pitch
);
711 rb
->cpp
= buffers
[i
].cpp
;
712 rb
->pitch
= buffers
[i
].pitch
;
713 rb
->base
.Width
= drawable
->w
;
714 rb
->base
.Height
= drawable
->h
;
718 rb
->tile_config
= radeon
->radeonScreen
->tile_config
;
719 rb
->group_bytes
= radeon
->radeonScreen
->group_bytes
;
720 rb
->num_channels
= radeon
->radeonScreen
->num_channels
;
721 rb
->num_banks
= radeon
->radeonScreen
->num_banks
;
722 rb
->r7xx_bank_op
= radeon
->radeonScreen
->r7xx_bank_op
;
724 if (buffers
[i
].attachment
== __DRI_BUFFER_STENCIL
&& depth_bo
) {
725 if (RADEON_DEBUG
& RADEON_DRI
)
726 fprintf(stderr
, "(reusing depth buffer as stencil)\n");
730 uint32_t tiling_flags
= 0, pitch
= 0;
733 bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
737 RADEON_GEM_DOMAIN_VRAM
,
742 fprintf(stderr
, "failed to attach %s %d\n",
743 regname
, buffers
[i
].name
);
747 ret
= radeon_bo_get_tiling(bo
, &tiling_flags
, &pitch
);
748 if (tiling_flags
& RADEON_TILING_MACRO
)
749 bo
->flags
|= RADEON_BO_FLAGS_MACRO_TILE
;
750 if (tiling_flags
& RADEON_TILING_MICRO
)
751 bo
->flags
|= RADEON_BO_FLAGS_MICRO_TILE
;
755 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH
) {
756 if (draw
->base
.Visual
.depthBits
== 16)
761 radeon_renderbuffer_set_bo(rb
, bo
);
764 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH_STENCIL
) {
765 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
767 struct radeon_bo
*stencil_bo
= NULL
;
770 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
771 if (name
== buffers
[i
].name
)
776 radeon_bo_ref(stencil_bo
);
777 radeon_renderbuffer_set_bo(rb
, stencil_bo
);
778 radeon_bo_unref(stencil_bo
);
783 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
786 /* Force the context `c' to be the current context and associate with it
789 GLboolean
radeonMakeCurrent(__DRIcontext
* driContextPriv
,
790 __DRIdrawable
* driDrawPriv
,
791 __DRIdrawable
* driReadPriv
)
793 radeonContextPtr radeon
;
794 struct radeon_framebuffer
*drfb
;
795 struct gl_framebuffer
*readfb
;
797 if (!driContextPriv
) {
798 if (RADEON_DEBUG
& RADEON_DRI
)
799 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
800 _mesa_make_current(NULL
, NULL
, NULL
);
804 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
805 drfb
= driDrawPriv
->driverPrivate
;
806 readfb
= driReadPriv
->driverPrivate
;
808 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
809 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
, GL_FALSE
);
810 if (driDrawPriv
!= driReadPriv
)
811 radeon_update_renderbuffers(driContextPriv
, driReadPriv
, GL_FALSE
);
812 _mesa_reference_renderbuffer(&radeon
->state
.color
.rb
,
813 &(radeon_get_renderbuffer(&drfb
->base
, BUFFER_BACK_LEFT
)->base
));
814 _mesa_reference_renderbuffer(&radeon
->state
.depth
.rb
,
815 &(radeon_get_renderbuffer(&drfb
->base
, BUFFER_DEPTH
)->base
));
817 radeon_make_renderbuffer_current(radeon
, drfb
);
820 if (RADEON_DEBUG
& RADEON_DRI
)
821 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__
, radeon
->glCtx
, drfb
, readfb
);
823 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
824 if (driReadPriv
!= driDrawPriv
)
825 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
827 _mesa_make_current(radeon
->glCtx
, &drfb
->base
, readfb
);
829 _mesa_update_state(radeon
->glCtx
);
831 if (radeon
->glCtx
->DrawBuffer
== &drfb
->base
) {
832 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
834 driDrawPriv
->vblFlags
=
835 (radeon
->radeonScreen
->irq
!= 0)
836 ? driGetDefaultVBlankFlags(&radeon
->
838 : VBLANK_FLAG_NO_IRQ
;
840 driDrawableInitVBlank(driDrawPriv
);
841 drfb
->vbl_waited
= driDrawPriv
->vblSeq
;
843 for (i
= 0; i
< 2; i
++) {
844 if (drfb
->color_rb
[i
])
845 drfb
->color_rb
[i
]->vbl_pending
= driDrawPriv
->vblSeq
;
850 radeon_window_moved(radeon
);
851 radeon_draw_buffer(radeon
->glCtx
, &drfb
->base
);
855 if (RADEON_DEBUG
& RADEON_DRI
)
856 fprintf(stderr
, "End %s\n", __FUNCTION__
);