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 case CHIP_FAMILY_BARTS
: return "BARTS";
104 case CHIP_FAMILY_TURKS
: return "TURKS";
105 case CHIP_FAMILY_CAICOS
: return "CAICOS";
106 default: return "unknown";
111 /* Return various strings for glGetString().
113 static const GLubyte
*radeonGetString(struct gl_context
* ctx
, GLenum name
)
115 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
116 static char buffer
[128];
120 if (IS_R600_CLASS(radeon
->radeonScreen
))
121 return (GLubyte
*) "Advanced Micro Devices, Inc.";
122 else if (IS_R300_CLASS(radeon
->radeonScreen
))
123 return (GLubyte
*) "DRI R300 Project";
125 return (GLubyte
*) "Tungsten Graphics, Inc.";
130 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
131 radeon
->radeonScreen
->AGPMode
;
132 const char* chipclass
;
133 char hardwarename
[32];
135 if (IS_R600_CLASS(radeon
->radeonScreen
))
137 else if (IS_R300_CLASS(radeon
->radeonScreen
))
139 else if (IS_R200_CLASS(radeon
->radeonScreen
))
144 sprintf(hardwarename
, "%s (%s %04X)",
146 get_chip_family_name(radeon
->radeonScreen
->chip_family
),
147 radeon
->radeonScreen
->device_id
);
149 offset
= driGetRendererString(buffer
, hardwarename
, DRIVER_DATE
,
152 if (IS_R600_CLASS(radeon
->radeonScreen
)) {
153 sprintf(&buffer
[offset
], " TCL");
154 } else if (IS_R300_CLASS(radeon
->radeonScreen
)) {
155 sprintf(&buffer
[offset
], " %sTCL",
156 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
159 sprintf(&buffer
[offset
], " %sTCL",
160 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
164 if (radeon
->radeonScreen
->driScreen
->dri2
.enabled
)
165 strcat(buffer
, " DRI2");
167 return (GLubyte
*) buffer
;
175 /* Initialize the driver's misc functions.
177 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
179 functions
->GetString
= radeonGetString
;
183 * Create and initialize all common fields of the context,
184 * including the Mesa context itself.
186 GLboolean
radeonInitContext(radeonContextPtr radeon
,
187 struct dd_function_table
* functions
,
188 const struct gl_config
* glVisual
,
189 __DRIcontext
* driContextPriv
,
190 void *sharedContextPrivate
)
192 __DRIscreen
*sPriv
= driContextPriv
->driScreenPriv
;
193 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
194 struct gl_context
* ctx
;
195 struct gl_context
* shareCtx
;
198 /* Fill in additional standard functions. */
199 radeonInitDriverFuncs(functions
);
201 radeon
->radeonScreen
= screen
;
202 /* Allocate and initialize the Mesa context */
203 if (sharedContextPrivate
)
204 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
207 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
208 functions
, (void *)radeon
);
213 driContextPriv
->driverPrivate
= radeon
;
215 meta_init_metaops(ctx
, &radeon
->meta
);
217 _mesa_meta_init(ctx
);
220 radeon
->dri
.context
= driContextPriv
;
221 radeon
->dri
.screen
= sPriv
;
222 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
223 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
224 radeon
->dri
.hwLockCount
= 0;
225 radeon
->dri
.fd
= sPriv
->fd
;
226 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
228 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
229 screen
->sarea_priv_offset
);
232 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
233 radeon
->iw
.irq_seq
= -1;
234 radeon
->irqsEmitted
= 0;
235 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
236 radeon
->radeonScreen
->irq
);
238 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
240 if (!radeon
->do_irqs
)
242 "IRQ's not enabled, falling back to %s: %d %d\n",
243 radeon
->do_usleeps
? "usleeps" : "busy waits",
244 fthrottle_mode
, radeon
->radeonScreen
->irq
);
246 radeon
->texture_depth
= driQueryOptioni (&radeon
->optionCache
,
248 if (radeon
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
249 radeon
->texture_depth
= ( glVisual
->rgbBits
> 16 ) ?
250 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
252 if (IS_R600_CLASS(radeon
->radeonScreen
)) {
253 radeon
->texture_row_align
= radeon
->radeonScreen
->group_bytes
;
254 radeon
->texture_rect_row_align
= radeon
->radeonScreen
->group_bytes
;
255 radeon
->texture_compressed_row_align
= radeon
->radeonScreen
->group_bytes
;
256 } else if (IS_R200_CLASS(radeon
->radeonScreen
) ||
257 IS_R100_CLASS(radeon
->radeonScreen
)) {
258 radeon
->texture_row_align
= 32;
259 radeon
->texture_rect_row_align
= 64;
260 radeon
->texture_compressed_row_align
= 32;
261 } else { /* R300 - not sure this is all correct */
262 int chip_family
= radeon
->radeonScreen
->chip_family
;
263 if (chip_family
== CHIP_FAMILY_RS600
||
264 chip_family
== CHIP_FAMILY_RS690
||
265 chip_family
== CHIP_FAMILY_RS740
)
266 radeon
->texture_row_align
= 64;
268 radeon
->texture_row_align
= 32;
269 radeon
->texture_rect_row_align
= 64;
270 radeon
->texture_compressed_row_align
= 32;
273 radeon_init_dma(radeon
);
281 * Destroy the command buffer and state atoms.
283 static void radeon_destroy_atom_list(radeonContextPtr radeon
)
285 struct radeon_state_atom
*atom
;
287 foreach(atom
, &radeon
->hw
.atomlist
) {
296 * Cleanup common context fields.
297 * Called by r200DestroyContext/r300DestroyContext
299 void radeonDestroyContext(__DRIcontext
*driContextPriv
)
301 #ifdef RADEON_BO_TRACK
304 GET_CURRENT_CONTEXT(ctx
);
305 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
306 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
310 _mesa_meta_free(radeon
->glCtx
);
312 if (radeon
== current
) {
313 _mesa_make_current(NULL
, NULL
, NULL
);
316 radeon_firevertices(radeon
);
317 if (!is_empty_list(&radeon
->dma
.reserved
)) {
318 rcommonFlushCmdBuf( radeon
, __FUNCTION__
);
321 radeonFreeDmaRegions(radeon
);
322 radeonReleaseArrays(radeon
->glCtx
, ~0);
323 meta_destroy_metaops(&radeon
->meta
);
324 if (radeon
->vtbl
.free_context
)
325 radeon
->vtbl
.free_context(radeon
->glCtx
);
326 _swsetup_DestroyContext( radeon
->glCtx
);
327 _tnl_DestroyContext( radeon
->glCtx
);
328 _vbo_DestroyContext( radeon
->glCtx
);
329 _swrast_DestroyContext( radeon
->glCtx
);
332 /* free the Mesa context */
333 _mesa_destroy_context(radeon
->glCtx
);
335 /* _mesa_destroy_context() might result in calls to functions that
336 * depend on the DriverCtx, so don't set it to NULL before.
338 * radeon->glCtx->DriverCtx = NULL;
340 /* free the option cache */
341 driDestroyOptionCache(&radeon
->optionCache
);
343 rcommonDestroyCmdBuf(radeon
);
345 radeon_destroy_atom_list(radeon
);
347 if (radeon
->state
.scissor
.pClipRects
) {
348 FREE(radeon
->state
.scissor
.pClipRects
);
349 radeon
->state
.scissor
.pClipRects
= 0;
351 #ifdef RADEON_BO_TRACK
352 track
= fopen("/tmp/tracklog", "w");
354 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
361 /* Force the context `c' to be unbound from its buffer.
363 GLboolean
radeonUnbindContext(__DRIcontext
* driContextPriv
)
365 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
367 if (RADEON_DEBUG
& RADEON_DRI
)
368 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,
371 /* Unset current context and dispath table */
372 _mesa_make_current(NULL
, NULL
, NULL
);
379 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
380 struct gl_framebuffer
*draw
)
382 /* if radeon->fake */
383 struct radeon_renderbuffer
*rb
;
385 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
387 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
388 radeon
->radeonScreen
->frontOffset
,
391 RADEON_GEM_DOMAIN_VRAM
,
394 rb
->cpp
= radeon
->radeonScreen
->cpp
;
395 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
397 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
399 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
400 radeon
->radeonScreen
->backOffset
,
403 RADEON_GEM_DOMAIN_VRAM
,
406 rb
->cpp
= radeon
->radeonScreen
->cpp
;
407 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
409 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
411 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
412 radeon
->radeonScreen
->depthOffset
,
415 RADEON_GEM_DOMAIN_VRAM
,
418 rb
->cpp
= radeon
->radeonScreen
->cpp
;
419 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
421 if ((rb
= (void *)draw
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
423 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
424 radeon
->radeonScreen
->depthOffset
,
427 RADEON_GEM_DOMAIN_VRAM
,
430 rb
->cpp
= radeon
->radeonScreen
->cpp
;
431 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
436 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
437 struct gl_framebuffer
*draw
)
439 int size
= 4096*4096*4;
440 /* if radeon->fake */
441 struct radeon_renderbuffer
*rb
;
443 if (radeon
->radeonScreen
->kernel_mm
) {
444 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
449 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
451 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
452 radeon
->radeonScreen
->frontOffset
+
453 radeon
->radeonScreen
->fbLocation
,
456 RADEON_GEM_DOMAIN_VRAM
,
459 rb
->cpp
= radeon
->radeonScreen
->cpp
;
460 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
462 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
464 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
465 radeon
->radeonScreen
->backOffset
+
466 radeon
->radeonScreen
->fbLocation
,
469 RADEON_GEM_DOMAIN_VRAM
,
472 rb
->cpp
= radeon
->radeonScreen
->cpp
;
473 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
475 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
477 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
478 radeon
->radeonScreen
->depthOffset
+
479 radeon
->radeonScreen
->fbLocation
,
482 RADEON_GEM_DOMAIN_VRAM
,
485 rb
->cpp
= radeon
->radeonScreen
->cpp
;
486 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
488 if ((rb
= (void *)draw
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
490 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
491 radeon
->radeonScreen
->depthOffset
+
492 radeon
->radeonScreen
->fbLocation
,
495 RADEON_GEM_DOMAIN_VRAM
,
498 rb
->cpp
= radeon
->radeonScreen
->cpp
;
499 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
504 radeon_bits_per_pixel(const struct radeon_renderbuffer
*rb
)
506 return _mesa_get_format_bytes(rb
->base
.Format
) * 8;
510 * Check if drawable has been invalidated by dri2InvalidateDrawable().
511 * Update renderbuffers if so. This prevents a client from accessing
512 * a backbuffer that has a swap pending but not yet completed.
514 * See intel_prepare_render for equivalent code in intel driver.
517 void radeon_prepare_render(radeonContextPtr radeon
)
519 __DRIcontext
*driContext
= radeon
->dri
.context
;
520 __DRIdrawable
*drawable
;
522 struct radeon_framebuffer
*draw
;
524 screen
= driContext
->driScreenPriv
;
525 if (!screen
->dri2
.loader
)
528 drawable
= driContext
->driDrawablePriv
;
529 if (drawable
->dri2
.stamp
!= driContext
->dri2
.draw_stamp
) {
530 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
531 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
533 /* Intel driver does the equivalent of this, no clue if it is needed:*/
534 draw
= drawable
->driverPrivate
;
535 radeon_draw_buffer(radeon
->glCtx
, &draw
->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
,
741 fprintf(stderr
, "failed to attach %s %d\n",
742 regname
, buffers
[i
].name
);
746 ret
= radeon_bo_get_tiling(bo
, &tiling_flags
, &pitch
);
747 if (tiling_flags
& RADEON_TILING_MACRO
)
748 bo
->flags
|= RADEON_BO_FLAGS_MACRO_TILE
;
749 if (tiling_flags
& RADEON_TILING_MICRO
)
750 bo
->flags
|= RADEON_BO_FLAGS_MICRO_TILE
;
754 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH
) {
755 if (draw
->base
.Visual
.depthBits
== 16)
760 radeon_renderbuffer_set_bo(rb
, bo
);
763 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH_STENCIL
) {
764 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
766 struct radeon_bo
*stencil_bo
= NULL
;
769 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
770 if (name
== buffers
[i
].name
)
775 radeon_bo_ref(stencil_bo
);
776 radeon_renderbuffer_set_bo(rb
, stencil_bo
);
777 radeon_bo_unref(stencil_bo
);
782 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
785 /* Force the context `c' to be the current context and associate with it
788 GLboolean
radeonMakeCurrent(__DRIcontext
* driContextPriv
,
789 __DRIdrawable
* driDrawPriv
,
790 __DRIdrawable
* driReadPriv
)
792 radeonContextPtr radeon
;
793 struct radeon_framebuffer
*rdrfb
;
794 struct gl_framebuffer
*drfb
, *readfb
;
796 if (!driContextPriv
) {
797 if (RADEON_DEBUG
& RADEON_DRI
)
798 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
799 _mesa_make_current(NULL
, NULL
, NULL
);
803 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
805 if(driDrawPriv
== NULL
&& driReadPriv
== NULL
) {
806 drfb
= _mesa_create_framebuffer(&radeon
->glCtx
->Visual
);
810 drfb
= driDrawPriv
->driverPrivate
;
811 readfb
= driReadPriv
->driverPrivate
;
814 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
816 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
, GL_FALSE
);
817 if (driDrawPriv
!= driReadPriv
)
818 radeon_update_renderbuffers(driContextPriv
, driReadPriv
, GL_FALSE
);
819 _mesa_reference_renderbuffer(&radeon
->state
.color
.rb
,
820 &(radeon_get_renderbuffer(drfb
, BUFFER_BACK_LEFT
)->base
));
821 _mesa_reference_renderbuffer(&radeon
->state
.depth
.rb
,
822 &(radeon_get_renderbuffer(drfb
, BUFFER_DEPTH
)->base
));
824 radeon_make_renderbuffer_current(radeon
, drfb
);
827 if (RADEON_DEBUG
& RADEON_DRI
)
828 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__
, radeon
->glCtx
, drfb
, readfb
);
831 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
832 if (driReadPriv
!= driDrawPriv
)
833 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
835 _mesa_make_current(radeon
->glCtx
, drfb
, readfb
);
836 if (driDrawPriv
== NULL
&& driReadPriv
== NULL
)
837 _mesa_reference_framebuffer(&drfb
, NULL
);
839 _mesa_update_state(radeon
->glCtx
);
841 if (radeon
->glCtx
->DrawBuffer
== drfb
) {
842 if(driDrawPriv
!= NULL
) {
843 rdrfb
= (struct radeon_framebuffer
*)drfb
;
844 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
846 driDrawPriv
->vblFlags
=
847 (radeon
->radeonScreen
->irq
!= 0)
848 ? driGetDefaultVBlankFlags(&radeon
->
850 : VBLANK_FLAG_NO_IRQ
;
852 driDrawableInitVBlank(driDrawPriv
);
853 rdrfb
->vbl_waited
= driDrawPriv
->vblSeq
;
855 for (i
= 0; i
< 2; i
++) {
856 if (rdrfb
->color_rb
[i
])
857 rdrfb
->color_rb
[i
]->vbl_pending
= driDrawPriv
->vblSeq
;
860 radeon_window_moved(radeon
);
863 radeon_draw_buffer(radeon
->glCtx
, drfb
);
867 if (RADEON_DEBUG
& RADEON_DRI
)
868 fprintf(stderr
, "End %s\n", __FUNCTION__
);