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"
51 int RADEON_DEBUG
= (0);
55 static const char* get_chip_family_name(int chip_family
)
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 case CHIP_FAMILY_R200
: return "R200";
64 case CHIP_FAMILY_RV250
: return "RV250";
65 case CHIP_FAMILY_RS300
: return "RS300";
66 case CHIP_FAMILY_RV280
: return "RV280";
67 case CHIP_FAMILY_R300
: return "R300";
68 case CHIP_FAMILY_R350
: return "R350";
69 case CHIP_FAMILY_RV350
: return "RV350";
70 case CHIP_FAMILY_RV380
: return "RV380";
71 case CHIP_FAMILY_R420
: return "R420";
72 case CHIP_FAMILY_RV410
: return "RV410";
73 case CHIP_FAMILY_RS400
: return "RS400";
74 case CHIP_FAMILY_RS600
: return "RS600";
75 case CHIP_FAMILY_RS690
: return "RS690";
76 case CHIP_FAMILY_RS740
: return "RS740";
77 case CHIP_FAMILY_RV515
: return "RV515";
78 case CHIP_FAMILY_R520
: return "R520";
79 case CHIP_FAMILY_RV530
: return "RV530";
80 case CHIP_FAMILY_R580
: return "R580";
81 case CHIP_FAMILY_RV560
: return "RV560";
82 case CHIP_FAMILY_RV570
: return "RV570";
83 case CHIP_FAMILY_R600
: return "R600";
84 case CHIP_FAMILY_RV610
: return "RV610";
85 case CHIP_FAMILY_RV630
: return "RV630";
86 case CHIP_FAMILY_RV670
: return "RV670";
87 case CHIP_FAMILY_RV620
: return "RV620";
88 case CHIP_FAMILY_RV635
: return "RV635";
89 case CHIP_FAMILY_RS780
: return "RS780";
90 case CHIP_FAMILY_RS880
: return "RS880";
91 case CHIP_FAMILY_RV770
: return "RV770";
92 case CHIP_FAMILY_RV730
: return "RV730";
93 case CHIP_FAMILY_RV710
: return "RV710";
94 case CHIP_FAMILY_RV740
: return "RV740";
95 case CHIP_FAMILY_CEDAR
: return "CEDAR";
96 case CHIP_FAMILY_REDWOOD
: return "REDWOOD";
97 case CHIP_FAMILY_JUNIPER
: return "JUNIPER";
98 case CHIP_FAMILY_CYPRESS
: return "CYPRESS";
99 case CHIP_FAMILY_HEMLOCK
: return "HEMLOCK";
100 case CHIP_FAMILY_PALM
: return "PALM";
101 case CHIP_FAMILY_SUMO
: return "SUMO";
102 case CHIP_FAMILY_SUMO2
: return "SUMO2";
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
, agp_mode
);
151 if (IS_R600_CLASS(radeon
->radeonScreen
)) {
152 sprintf(&buffer
[offset
], " TCL");
153 } else if (IS_R300_CLASS(radeon
->radeonScreen
)) {
154 sprintf(&buffer
[offset
], " %sTCL",
155 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
158 sprintf(&buffer
[offset
], " %sTCL",
159 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
163 if (radeon
->radeonScreen
->driScreen
->dri2
.enabled
)
164 strcat(buffer
, " DRI2");
166 return (GLubyte
*) buffer
;
174 /* Initialize the driver's misc functions.
176 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
178 functions
->GetString
= radeonGetString
;
182 * Create and initialize all common fields of the context,
183 * including the Mesa context itself.
185 GLboolean
radeonInitContext(radeonContextPtr radeon
,
186 struct dd_function_table
* functions
,
187 const struct gl_config
* glVisual
,
188 __DRIcontext
* driContextPriv
,
189 void *sharedContextPrivate
)
191 __DRIscreen
*sPriv
= driContextPriv
->driScreenPriv
;
192 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
193 struct gl_context
* ctx
;
194 struct gl_context
* shareCtx
;
197 /* Fill in additional standard functions. */
198 radeonInitDriverFuncs(functions
);
200 radeon
->radeonScreen
= screen
;
201 /* Allocate and initialize the Mesa context */
202 if (sharedContextPrivate
)
203 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
206 radeon
->glCtx
= _mesa_create_context(API_OPENGL
, glVisual
, shareCtx
,
207 functions
, (void *)radeon
);
212 driContextPriv
->driverPrivate
= radeon
;
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 if (radeon
->vtbl
.free_context
)
321 radeon
->vtbl
.free_context(radeon
->glCtx
);
322 _swsetup_DestroyContext( radeon
->glCtx
);
323 _tnl_DestroyContext( radeon
->glCtx
);
324 _vbo_DestroyContext( radeon
->glCtx
);
325 _swrast_DestroyContext( radeon
->glCtx
);
328 /* free the Mesa context */
329 _mesa_destroy_context(radeon
->glCtx
);
331 /* _mesa_destroy_context() might result in calls to functions that
332 * depend on the DriverCtx, so don't set it to NULL before.
334 * radeon->glCtx->DriverCtx = NULL;
336 /* free the option cache */
337 driDestroyOptionCache(&radeon
->optionCache
);
339 rcommonDestroyCmdBuf(radeon
);
341 radeon_destroy_atom_list(radeon
);
343 if (radeon
->state
.scissor
.pClipRects
) {
344 FREE(radeon
->state
.scissor
.pClipRects
);
345 radeon
->state
.scissor
.pClipRects
= 0;
347 #ifdef RADEON_BO_TRACK
348 track
= fopen("/tmp/tracklog", "w");
350 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
357 /* Force the context `c' to be unbound from its buffer.
359 GLboolean
radeonUnbindContext(__DRIcontext
* driContextPriv
)
361 radeonContextPtr radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
363 if (RADEON_DEBUG
& RADEON_DRI
)
364 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
,
367 /* Unset current context and dispath table */
368 _mesa_make_current(NULL
, NULL
, NULL
);
375 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
376 struct gl_framebuffer
*draw
)
378 /* if radeon->fake */
379 struct radeon_renderbuffer
*rb
;
381 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
383 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
384 radeon
->radeonScreen
->frontOffset
,
387 RADEON_GEM_DOMAIN_VRAM
,
390 rb
->cpp
= radeon
->radeonScreen
->cpp
;
391 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
393 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
395 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
396 radeon
->radeonScreen
->backOffset
,
399 RADEON_GEM_DOMAIN_VRAM
,
402 rb
->cpp
= radeon
->radeonScreen
->cpp
;
403 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
405 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
407 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
408 radeon
->radeonScreen
->depthOffset
,
411 RADEON_GEM_DOMAIN_VRAM
,
414 rb
->cpp
= radeon
->radeonScreen
->cpp
;
415 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
417 if ((rb
= (void *)draw
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
419 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
420 radeon
->radeonScreen
->depthOffset
,
423 RADEON_GEM_DOMAIN_VRAM
,
426 rb
->cpp
= radeon
->radeonScreen
->cpp
;
427 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
432 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
433 struct gl_framebuffer
*draw
)
435 int size
= 4096*4096*4;
436 /* if radeon->fake */
437 struct radeon_renderbuffer
*rb
;
439 if (radeon
->radeonScreen
->kernel_mm
) {
440 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
445 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
447 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
448 radeon
->radeonScreen
->frontOffset
+
449 radeon
->radeonScreen
->fbLocation
,
452 RADEON_GEM_DOMAIN_VRAM
,
455 rb
->cpp
= radeon
->radeonScreen
->cpp
;
456 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
458 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
460 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
461 radeon
->radeonScreen
->backOffset
+
462 radeon
->radeonScreen
->fbLocation
,
465 RADEON_GEM_DOMAIN_VRAM
,
468 rb
->cpp
= radeon
->radeonScreen
->cpp
;
469 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
471 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
473 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
474 radeon
->radeonScreen
->depthOffset
+
475 radeon
->radeonScreen
->fbLocation
,
478 RADEON_GEM_DOMAIN_VRAM
,
481 rb
->cpp
= radeon
->radeonScreen
->cpp
;
482 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
484 if ((rb
= (void *)draw
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
486 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
487 radeon
->radeonScreen
->depthOffset
+
488 radeon
->radeonScreen
->fbLocation
,
491 RADEON_GEM_DOMAIN_VRAM
,
494 rb
->cpp
= radeon
->radeonScreen
->cpp
;
495 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
500 radeon_bits_per_pixel(const struct radeon_renderbuffer
*rb
)
502 return _mesa_get_format_bytes(rb
->base
.Format
) * 8;
506 * Check if drawable has been invalidated by dri2InvalidateDrawable().
507 * Update renderbuffers if so. This prevents a client from accessing
508 * a backbuffer that has a swap pending but not yet completed.
510 * See intel_prepare_render for equivalent code in intel driver.
513 void radeon_prepare_render(radeonContextPtr radeon
)
515 __DRIcontext
*driContext
= radeon
->dri
.context
;
516 __DRIdrawable
*drawable
;
519 screen
= driContext
->driScreenPriv
;
520 if (!screen
->dri2
.loader
)
523 drawable
= driContext
->driDrawablePriv
;
524 if (drawable
->dri2
.stamp
!= driContext
->dri2
.draw_stamp
) {
525 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
526 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
528 /* Intel driver does the equivalent of this, no clue if it is needed:*/
529 radeon_draw_buffer(radeon
->glCtx
, radeon
->glCtx
->DrawBuffer
);
531 driContext
->dri2
.draw_stamp
= drawable
->dri2
.stamp
;
534 drawable
= driContext
->driReadablePriv
;
535 if (drawable
->dri2
.stamp
!= driContext
->dri2
.read_stamp
) {
536 if (drawable
->lastStamp
!= drawable
->dri2
.stamp
)
537 radeon_update_renderbuffers(driContext
, drawable
, GL_FALSE
);
538 driContext
->dri2
.read_stamp
= drawable
->dri2
.stamp
;
541 /* If we're currently rendering to the front buffer, the rendering
542 * that will happen next will probably dirty the front buffer. So
543 * mark it as dirty here.
545 if (radeon
->is_front_buffer_rendering
)
546 radeon
->front_buffer_dirty
= GL_TRUE
;
550 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
,
551 GLboolean front_only
)
553 unsigned int attachments
[10];
554 __DRIbuffer
*buffers
= NULL
;
556 struct radeon_renderbuffer
*rb
;
558 struct radeon_framebuffer
*draw
;
559 radeonContextPtr radeon
;
561 struct radeon_bo
*depth_bo
= NULL
, *bo
;
563 if (RADEON_DEBUG
& RADEON_DRI
)
564 fprintf(stderr
, "enter %s, drawable %p\n", __func__
, drawable
);
566 draw
= drawable
->driverPrivate
;
567 screen
= context
->driScreenPriv
;
568 radeon
= (radeonContextPtr
) context
->driverPrivate
;
570 /* Set this up front, so that in case our buffers get invalidated
571 * while we're getting new buffers, we don't clobber the stamp and
572 * thus ignore the invalidate. */
573 drawable
->lastStamp
= drawable
->dri2
.stamp
;
575 if (screen
->dri2
.loader
576 && (screen
->dri2
.loader
->base
.version
> 2)
577 && (screen
->dri2
.loader
->getBuffersWithFormat
!= NULL
)) {
578 struct radeon_renderbuffer
*depth_rb
;
579 struct radeon_renderbuffer
*stencil_rb
;
582 if ((front_only
|| radeon
->is_front_buffer_rendering
||
583 radeon
->is_front_buffer_reading
||
585 && draw
->color_rb
[0]) {
586 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
587 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[0]);
591 if (draw
->color_rb
[1]) {
592 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
593 attachments
[i
++] = radeon_bits_per_pixel(draw
->color_rb
[1]);
596 depth_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
597 stencil_rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
599 if ((depth_rb
!= NULL
) && (stencil_rb
!= NULL
)) {
600 attachments
[i
++] = __DRI_BUFFER_DEPTH_STENCIL
;
601 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
602 } else if (depth_rb
!= NULL
) {
603 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
604 attachments
[i
++] = radeon_bits_per_pixel(depth_rb
);
605 } else if (stencil_rb
!= NULL
) {
606 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
607 attachments
[i
++] = radeon_bits_per_pixel(stencil_rb
);
611 buffers
= (*screen
->dri2
.loader
->getBuffersWithFormat
)(drawable
,
616 drawable
->loaderPrivate
);
617 } else if (screen
->dri2
.loader
) {
619 if (draw
->color_rb
[0])
620 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
622 if (draw
->color_rb
[1])
623 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
624 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
))
625 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
626 if (radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
))
627 attachments
[i
++] = __DRI_BUFFER_STENCIL
;
630 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
635 drawable
->loaderPrivate
);
641 /* set one cliprect to cover the whole drawable */
646 drawable
->numClipRects
= 1;
647 drawable
->pClipRects
[0].x1
= 0;
648 drawable
->pClipRects
[0].y1
= 0;
649 drawable
->pClipRects
[0].x2
= drawable
->w
;
650 drawable
->pClipRects
[0].y2
= drawable
->h
;
651 drawable
->numBackClipRects
= 1;
652 drawable
->pBackClipRects
[0].x1
= 0;
653 drawable
->pBackClipRects
[0].y1
= 0;
654 drawable
->pBackClipRects
[0].x2
= drawable
->w
;
655 drawable
->pBackClipRects
[0].y2
= drawable
->h
;
656 for (i
= 0; i
< count
; i
++) {
657 switch (buffers
[i
].attachment
) {
658 case __DRI_BUFFER_FRONT_LEFT
:
659 rb
= draw
->color_rb
[0];
660 regname
= "dri2 front buffer";
662 case __DRI_BUFFER_FAKE_FRONT_LEFT
:
663 rb
= draw
->color_rb
[0];
664 regname
= "dri2 fake front buffer";
666 case __DRI_BUFFER_BACK_LEFT
:
667 rb
= draw
->color_rb
[1];
668 regname
= "dri2 back buffer";
670 case __DRI_BUFFER_DEPTH
:
671 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
672 regname
= "dri2 depth buffer";
674 case __DRI_BUFFER_DEPTH_STENCIL
:
675 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_DEPTH
);
676 regname
= "dri2 depth / stencil buffer";
678 case __DRI_BUFFER_STENCIL
:
679 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
680 regname
= "dri2 stencil buffer";
682 case __DRI_BUFFER_ACCUM
:
685 "unhandled buffer attach event, attacment type %d\n",
686 buffers
[i
].attachment
);
694 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
695 if (name
== buffers
[i
].name
)
699 if (RADEON_DEBUG
& RADEON_DRI
)
701 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
702 regname
, buffers
[i
].name
, buffers
[i
].attachment
,
703 buffers
[i
].cpp
, buffers
[i
].pitch
);
705 rb
->cpp
= buffers
[i
].cpp
;
706 rb
->pitch
= buffers
[i
].pitch
;
707 rb
->base
.Width
= drawable
->w
;
708 rb
->base
.Height
= drawable
->h
;
712 rb
->tile_config
= radeon
->radeonScreen
->tile_config
;
713 rb
->group_bytes
= radeon
->radeonScreen
->group_bytes
;
714 rb
->num_channels
= radeon
->radeonScreen
->num_channels
;
715 rb
->num_banks
= radeon
->radeonScreen
->num_banks
;
716 rb
->r7xx_bank_op
= radeon
->radeonScreen
->r7xx_bank_op
;
718 if (buffers
[i
].attachment
== __DRI_BUFFER_STENCIL
&& depth_bo
) {
719 if (RADEON_DEBUG
& RADEON_DRI
)
720 fprintf(stderr
, "(reusing depth buffer as stencil)\n");
724 uint32_t tiling_flags
= 0, pitch
= 0;
727 bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
731 RADEON_GEM_DOMAIN_VRAM
,
735 fprintf(stderr
, "failed to attach %s %d\n",
736 regname
, buffers
[i
].name
);
740 ret
= radeon_bo_get_tiling(bo
, &tiling_flags
, &pitch
);
741 if (tiling_flags
& RADEON_TILING_MACRO
)
742 bo
->flags
|= RADEON_BO_FLAGS_MACRO_TILE
;
743 if (tiling_flags
& RADEON_TILING_MICRO
)
744 bo
->flags
|= RADEON_BO_FLAGS_MICRO_TILE
;
748 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH
) {
749 if (draw
->base
.Visual
.depthBits
== 16)
754 radeon_renderbuffer_set_bo(rb
, bo
);
757 if (buffers
[i
].attachment
== __DRI_BUFFER_DEPTH_STENCIL
) {
758 rb
= radeon_get_renderbuffer(&draw
->base
, BUFFER_STENCIL
);
760 struct radeon_bo
*stencil_bo
= NULL
;
763 uint32_t name
= radeon_gem_name_bo(rb
->bo
);
764 if (name
== buffers
[i
].name
)
769 radeon_bo_ref(stencil_bo
);
770 radeon_renderbuffer_set_bo(rb
, stencil_bo
);
771 radeon_bo_unref(stencil_bo
);
776 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
779 /* Force the context `c' to be the current context and associate with it
782 GLboolean
radeonMakeCurrent(__DRIcontext
* driContextPriv
,
783 __DRIdrawable
* driDrawPriv
,
784 __DRIdrawable
* driReadPriv
)
786 radeonContextPtr radeon
;
787 struct radeon_framebuffer
*rdrfb
;
788 struct gl_framebuffer
*drfb
, *readfb
;
790 if (!driContextPriv
) {
791 if (RADEON_DEBUG
& RADEON_DRI
)
792 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
793 _mesa_make_current(NULL
, NULL
, NULL
);
797 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
799 if(driDrawPriv
== NULL
&& driReadPriv
== NULL
) {
800 drfb
= _mesa_create_framebuffer(&radeon
->glCtx
->Visual
);
804 drfb
= driDrawPriv
->driverPrivate
;
805 readfb
= driReadPriv
->driverPrivate
;
808 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
810 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
, GL_FALSE
);
811 if (driDrawPriv
!= driReadPriv
)
812 radeon_update_renderbuffers(driContextPriv
, driReadPriv
, GL_FALSE
);
813 _mesa_reference_renderbuffer(&radeon
->state
.color
.rb
,
814 &(radeon_get_renderbuffer(drfb
, BUFFER_BACK_LEFT
)->base
));
815 _mesa_reference_renderbuffer(&radeon
->state
.depth
.rb
,
816 &(radeon_get_renderbuffer(drfb
, BUFFER_DEPTH
)->base
));
818 radeon_make_renderbuffer_current(radeon
, drfb
);
821 if (RADEON_DEBUG
& RADEON_DRI
)
822 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__
, radeon
->glCtx
, drfb
, readfb
);
825 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
826 if (driReadPriv
!= driDrawPriv
)
827 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
829 _mesa_make_current(radeon
->glCtx
, drfb
, readfb
);
830 if (driDrawPriv
== NULL
&& driReadPriv
== NULL
)
831 _mesa_reference_framebuffer(&drfb
, NULL
);
833 _mesa_update_state(radeon
->glCtx
);
835 if (radeon
->glCtx
->DrawBuffer
== drfb
) {
836 if(driDrawPriv
!= NULL
) {
837 rdrfb
= (struct radeon_framebuffer
*)drfb
;
838 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
840 driDrawPriv
->vblFlags
=
841 (radeon
->radeonScreen
->irq
!= 0)
842 ? driGetDefaultVBlankFlags(&radeon
->
844 : VBLANK_FLAG_NO_IRQ
;
846 driDrawableInitVBlank(driDrawPriv
);
847 rdrfb
->vbl_waited
= driDrawPriv
->vblSeq
;
849 for (i
= 0; i
< 2; i
++) {
850 if (rdrfb
->color_rb
[i
])
851 rdrfb
->color_rb
[i
]->vbl_pending
= driDrawPriv
->vblSeq
;
854 radeon_window_moved(radeon
);
857 radeon_draw_buffer(radeon
->glCtx
, drfb
);
861 if (RADEON_DEBUG
& RADEON_DRI
)
862 fprintf(stderr
, "End %s\n", __FUNCTION__
);