1 /**************************************************************************
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
37 - Scissor implementation
38 - buffer swap/copy ioctls
41 - cmdbuffer management
45 #include "main/glheader.h"
46 #include "main/imports.h"
47 #include "main/context.h"
48 #include "main/api_arrayelt.h"
49 #include "main/enums.h"
50 #include "main/colormac.h"
51 #include "main/light.h"
52 #include "main/framebuffer.h"
53 #include "main/simple_list.h"
54 #include "main/renderbuffer.h"
55 #include "swrast/swrast.h"
58 #include "tnl/t_pipeline.h"
59 #include "swrast_setup/swrast_setup.h"
61 #include "main/blend.h"
62 #include "main/bufferobj.h"
63 #include "main/buffers.h"
64 #include "main/depth.h"
65 #include "main/shaders.h"
66 #include "main/texstate.h"
67 #include "main/varray.h"
68 #include "glapi/dispatch.h"
69 #include "swrast/swrast.h"
70 #include "main/stencil.h"
71 #include "main/matrix.h"
72 #include "main/attrib.h"
73 #include "main/enable.h"
74 #include "main/viewport.h"
79 #include "radeon_common.h"
80 #include "radeon_bocs_wrapper.h"
81 #include "radeon_lock.h"
82 #include "radeon_drm.h"
83 #include "radeon_mipmap_tree.h"
85 #define DEBUG_CMDBUF 0
87 /* =============================================================
91 static GLboolean
intersect_rect(drm_clip_rect_t
* out
,
92 drm_clip_rect_t
* a
, drm_clip_rect_t
* b
)
103 if (out
->x1
>= out
->x2
)
105 if (out
->y1
>= out
->y2
)
110 void radeonRecalcScissorRects(radeonContextPtr radeon
)
112 drm_clip_rect_t
*out
;
115 /* Grow cliprect store?
117 if (radeon
->state
.scissor
.numAllocedClipRects
< radeon
->numClipRects
) {
118 while (radeon
->state
.scissor
.numAllocedClipRects
<
119 radeon
->numClipRects
) {
120 radeon
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
121 radeon
->state
.scissor
.numAllocedClipRects
*= 2;
124 if (radeon
->state
.scissor
.pClipRects
)
125 FREE(radeon
->state
.scissor
.pClipRects
);
127 radeon
->state
.scissor
.pClipRects
=
128 MALLOC(radeon
->state
.scissor
.numAllocedClipRects
*
129 sizeof(drm_clip_rect_t
));
131 if (radeon
->state
.scissor
.pClipRects
== NULL
) {
132 radeon
->state
.scissor
.numAllocedClipRects
= 0;
137 out
= radeon
->state
.scissor
.pClipRects
;
138 radeon
->state
.scissor
.numClipRects
= 0;
140 for (i
= 0; i
< radeon
->numClipRects
; i
++) {
141 if (intersect_rect(out
,
142 &radeon
->pClipRects
[i
],
143 &radeon
->state
.scissor
.rect
)) {
144 radeon
->state
.scissor
.numClipRects
++;
150 void radeon_get_cliprects(radeonContextPtr radeon
,
151 struct drm_clip_rect
**cliprects
,
152 unsigned int *num_cliprects
,
153 int *x_off
, int *y_off
)
155 __DRIdrawablePrivate
*dPriv
= radeon
->dri
.drawable
;
156 struct radeon_framebuffer
*rfb
= dPriv
->driverPrivate
;
158 if (radeon
->constant_cliprect
) {
159 radeon
->fboRect
.x1
= 0;
160 radeon
->fboRect
.y1
= 0;
161 radeon
->fboRect
.x2
= radeon
->glCtx
->DrawBuffer
->Width
;
162 radeon
->fboRect
.y2
= radeon
->glCtx
->DrawBuffer
->Height
;
164 *cliprects
= &radeon
->fboRect
;
168 } else if (radeon
->front_cliprects
||
169 rfb
->pf_active
|| dPriv
->numBackClipRects
== 0) {
170 *cliprects
= dPriv
->pClipRects
;
171 *num_cliprects
= dPriv
->numClipRects
;
175 *num_cliprects
= dPriv
->numBackClipRects
;
176 *cliprects
= dPriv
->pBackClipRects
;
177 *x_off
= dPriv
->backX
;
178 *y_off
= dPriv
->backY
;
183 * Update cliprects and scissors.
185 void radeonSetCliprects(radeonContextPtr radeon
)
187 __DRIdrawablePrivate
*const drawable
= radeon
->dri
.drawable
;
188 __DRIdrawablePrivate
*const readable
= radeon
->dri
.readable
;
189 struct radeon_framebuffer
*const draw_rfb
= drawable
->driverPrivate
;
190 struct radeon_framebuffer
*const read_rfb
= readable
->driverPrivate
;
193 radeon_get_cliprects(radeon
, &radeon
->pClipRects
,
194 &radeon
->numClipRects
, &x_off
, &y_off
);
196 if ((draw_rfb
->base
.Width
!= drawable
->w
) ||
197 (draw_rfb
->base
.Height
!= drawable
->h
)) {
198 _mesa_resize_framebuffer(radeon
->glCtx
, &draw_rfb
->base
,
199 drawable
->w
, drawable
->h
);
200 draw_rfb
->base
.Initialized
= GL_TRUE
;
203 if (drawable
!= readable
) {
204 if ((read_rfb
->base
.Width
!= readable
->w
) ||
205 (read_rfb
->base
.Height
!= readable
->h
)) {
206 _mesa_resize_framebuffer(radeon
->glCtx
, &read_rfb
->base
,
207 readable
->w
, readable
->h
);
208 read_rfb
->base
.Initialized
= GL_TRUE
;
212 if (radeon
->state
.scissor
.enabled
)
213 radeonRecalcScissorRects(radeon
);
219 void radeonUpdateScissor( GLcontext
*ctx
)
221 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
223 if ( rmesa
->dri
.drawable
) {
224 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
226 int x
= ctx
->Scissor
.X
;
227 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
228 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
229 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
231 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
232 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
233 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
234 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
236 radeonRecalcScissorRects( rmesa
);
240 /* =============================================================
244 void radeonScissor(GLcontext
* ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
246 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
247 if (ctx
->Scissor
.Enabled
) {
248 /* We don't pipeline cliprect changes */
249 radeon_firevertices(radeon
);
250 radeonUpdateScissor(ctx
);
255 /* ================================================================
256 * SwapBuffers with client-side throttling
259 static uint32_t radeonGetLastFrame(radeonContextPtr radeon
)
261 drm_radeon_getparam_t gp
;
265 gp
.param
= RADEON_PARAM_LAST_FRAME
;
266 gp
.value
= (int *)&frame
;
267 ret
= drmCommandWriteRead(radeon
->dri
.fd
, DRM_RADEON_GETPARAM
,
270 fprintf(stderr
, "%s: drmRadeonGetParam: %d\n", __FUNCTION__
,
278 uint32_t radeonGetAge(radeonContextPtr radeon
)
280 drm_radeon_getparam_t gp
;
284 gp
.param
= RADEON_PARAM_LAST_CLEAR
;
285 gp
.value
= (int *)&age
;
286 ret
= drmCommandWriteRead(radeon
->dri
.fd
, DRM_RADEON_GETPARAM
,
289 fprintf(stderr
, "%s: drmRadeonGetParam: %d\n", __FUNCTION__
,
297 static void radeonEmitIrqLocked(radeonContextPtr radeon
)
299 drm_radeon_irq_emit_t ie
;
302 ie
.irq_seq
= &radeon
->iw
.irq_seq
;
303 ret
= drmCommandWriteRead(radeon
->dri
.fd
, DRM_RADEON_IRQ_EMIT
,
306 fprintf(stderr
, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__
,
312 static void radeonWaitIrq(radeonContextPtr radeon
)
317 ret
= drmCommandWrite(radeon
->dri
.fd
, DRM_RADEON_IRQ_WAIT
,
318 &radeon
->iw
, sizeof(radeon
->iw
));
319 } while (ret
&& (errno
== EINTR
|| errno
== EBUSY
));
322 fprintf(stderr
, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__
,
328 static void radeonWaitForFrameCompletion(radeonContextPtr radeon
)
330 drm_radeon_sarea_t
*sarea
= radeon
->sarea
;
332 if (radeon
->do_irqs
) {
333 if (radeonGetLastFrame(radeon
) < sarea
->last_frame
) {
334 if (!radeon
->irqsEmitted
) {
335 while (radeonGetLastFrame(radeon
) <
338 UNLOCK_HARDWARE(radeon
);
339 radeonWaitIrq(radeon
);
340 LOCK_HARDWARE(radeon
);
342 radeon
->irqsEmitted
= 10;
345 if (radeon
->irqsEmitted
) {
346 radeonEmitIrqLocked(radeon
);
347 radeon
->irqsEmitted
--;
350 while (radeonGetLastFrame(radeon
) < sarea
->last_frame
) {
351 UNLOCK_HARDWARE(radeon
);
352 if (radeon
->do_usleeps
)
354 LOCK_HARDWARE(radeon
);
360 void radeonWaitForIdleLocked(radeonContextPtr radeon
)
366 ret
= drmCommandNone(radeon
->dri
.fd
, DRM_RADEON_CP_IDLE
);
369 } while (ret
&& ++i
< 100);
372 UNLOCK_HARDWARE(radeon
);
373 fprintf(stderr
, "Error: R300 timed out... exiting\n");
378 static void radeonWaitForIdle(radeonContextPtr radeon
)
380 LOCK_HARDWARE(radeon
);
381 radeonWaitForIdleLocked(radeon
);
382 UNLOCK_HARDWARE(radeon
);
385 static void radeon_flip_renderbuffers(struct radeon_framebuffer
*rfb
)
387 int current_page
= rfb
->pf_current_page
;
388 int next_page
= (current_page
+ 1) % rfb
->pf_num_pages
;
389 struct gl_renderbuffer
*tmp_rb
;
391 /* Exchange renderbuffers if necessary but make sure their
392 * reference counts are preserved.
394 if (rfb
->color_rb
[current_page
] &&
395 rfb
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
!=
396 &rfb
->color_rb
[current_page
]->base
) {
398 _mesa_reference_renderbuffer(&tmp_rb
,
399 rfb
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
);
400 tmp_rb
= &rfb
->color_rb
[current_page
]->base
;
401 _mesa_reference_renderbuffer(&rfb
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
, tmp_rb
);
402 _mesa_reference_renderbuffer(&tmp_rb
, NULL
);
405 if (rfb
->color_rb
[next_page
] &&
406 rfb
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
!=
407 &rfb
->color_rb
[next_page
]->base
) {
409 _mesa_reference_renderbuffer(&tmp_rb
,
410 rfb
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
411 tmp_rb
= &rfb
->color_rb
[next_page
]->base
;
412 _mesa_reference_renderbuffer(&rfb
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
, tmp_rb
);
413 _mesa_reference_renderbuffer(&tmp_rb
, NULL
);
417 /* Copy the back color buffer to the front color buffer.
419 void radeonCopyBuffer( __DRIdrawablePrivate
*dPriv
,
420 const drm_clip_rect_t
*rect
)
422 radeonContextPtr rmesa
;
423 struct radeon_framebuffer
*rfb
;
427 assert(dPriv
->driContextPriv
);
428 assert(dPriv
->driContextPriv
->driverPrivate
);
430 rmesa
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
432 LOCK_HARDWARE(rmesa
);
434 rfb
= dPriv
->driverPrivate
;
436 if ( RADEON_DEBUG
& DEBUG_IOCTL
) {
437 fprintf( stderr
, "\n%s( %p )\n\n", __FUNCTION__
, (void *) rmesa
->glCtx
);
440 nbox
= dPriv
->numClipRects
; /* must be in locked region */
442 for ( i
= 0 ; i
< nbox
; ) {
443 GLint nr
= MIN2( i
+ RADEON_NR_SAREA_CLIPRECTS
, nbox
);
444 drm_clip_rect_t
*box
= dPriv
->pClipRects
;
445 drm_clip_rect_t
*b
= rmesa
->sarea
->boxes
;
448 for ( ; i
< nr
; i
++ ) {
454 if (rect
->x1
> b
->x1
)
456 if (rect
->y1
> b
->y1
)
458 if (rect
->x2
< b
->x2
)
460 if (rect
->y2
< b
->y2
)
463 if (b
->x1
>= b
->x2
|| b
->y1
>= b
->y2
)
470 rmesa
->sarea
->nbox
= n
;
475 ret
= drmCommandNone( rmesa
->dri
.fd
, DRM_RADEON_SWAP
);
478 fprintf( stderr
, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret
);
479 UNLOCK_HARDWARE( rmesa
);
484 UNLOCK_HARDWARE( rmesa
);
487 static int radeonScheduleSwap(__DRIdrawablePrivate
*dPriv
, GLboolean
*missed_target
)
489 radeonContextPtr rmesa
;
491 rmesa
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
492 radeon_firevertices(rmesa
);
494 LOCK_HARDWARE( rmesa
);
496 if (!dPriv
->numClipRects
) {
497 UNLOCK_HARDWARE(rmesa
);
498 usleep(10000); /* throttle invisible client 10ms */
502 radeonWaitForFrameCompletion(rmesa
);
504 UNLOCK_HARDWARE(rmesa
);
505 driWaitForVBlank(dPriv
, missed_target
);
510 static GLboolean
radeonPageFlip( __DRIdrawablePrivate
*dPriv
)
512 radeonContextPtr radeon
;
514 __DRIscreenPrivate
*psp
;
515 struct radeon_renderbuffer
*rrb
;
516 struct radeon_framebuffer
*rfb
;
519 assert(dPriv
->driContextPriv
);
520 assert(dPriv
->driContextPriv
->driverPrivate
);
522 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
523 rfb
= dPriv
->driverPrivate
;
524 rrb
= (void *)rfb
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
526 psp
= dPriv
->driScreenPriv
;
528 LOCK_HARDWARE(radeon
);
530 if ( RADEON_DEBUG
& DEBUG_IOCTL
) {
531 fprintf(stderr
, "%s: pfCurrentPage: %d %d\n", __FUNCTION__
,
532 radeon
->sarea
->pfCurrentPage
, radeon
->sarea
->pfState
);
534 drm_clip_rect_t
*box
= dPriv
->pClipRects
;
535 drm_clip_rect_t
*b
= radeon
->sarea
->boxes
;
537 radeon
->sarea
->nbox
= 1;
539 ret
= drmCommandNone( radeon
->dri
.fd
, DRM_RADEON_FLIP
);
541 UNLOCK_HARDWARE(radeon
);
544 fprintf( stderr
, "DRM_RADEON_FLIP: return = %d\n", ret
);
551 rfb
->pf_current_page
= radeon
->sarea
->pfCurrentPage
;
552 radeon_flip_renderbuffers(rfb
);
553 radeon_draw_buffer(radeon
->glCtx
, &rfb
->base
);
560 * Swap front and back buffer.
562 void radeonSwapBuffers(__DRIdrawablePrivate
* dPriv
)
565 __DRIscreenPrivate
*psp
;
567 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
568 radeonContextPtr radeon
;
571 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
574 if (ctx
->Visual
.doubleBufferMode
) {
575 GLboolean missed_target
;
576 struct radeon_framebuffer
*rfb
= dPriv
->driverPrivate
;
577 _mesa_notifySwapBuffers(ctx
);/* flush pending rendering comands */
579 radeonScheduleSwap(dPriv
, &missed_target
);
581 if (rfb
->pf_active
) {
582 radeonPageFlip(dPriv
);
584 radeonCopyBuffer(dPriv
, NULL
);
587 psp
= dPriv
->driScreenPriv
;
590 (*psp
->systemTime
->getUST
)( & ust
);
591 if ( missed_target
) {
592 rfb
->swap_missed_count
++;
593 rfb
->swap_missed_ust
= ust
- rfb
->swap_ust
;
597 radeon
->hw
.all_dirty
= GL_TRUE
;
600 /* XXX this shouldn't be an error but we can't handle it for now */
601 _mesa_problem(NULL
, "%s: drawable has no context!",
606 void radeonCopySubBuffer(__DRIdrawablePrivate
* dPriv
,
607 int x
, int y
, int w
, int h
)
609 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
610 radeonContextPtr radeon
;
613 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
616 if (ctx
->Visual
.doubleBufferMode
) {
617 drm_clip_rect_t rect
;
618 rect
.x1
= x
+ dPriv
->x
;
619 rect
.y1
= (dPriv
->h
- y
- h
) + dPriv
->y
;
620 rect
.x2
= rect
.x1
+ w
;
621 rect
.y2
= rect
.y1
+ h
;
622 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
623 radeonCopyBuffer(dPriv
, &rect
);
626 /* XXX this shouldn't be an error but we can't handle it for now */
627 _mesa_problem(NULL
, "%s: drawable has no context!",
632 void radeon_draw_buffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
)
634 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
635 struct radeon_renderbuffer
*rrbDepth
= NULL
, *rrbStencil
= NULL
,
641 /* this can happen during the initial context initialization */
645 /* radeons only handle 1 color draw so far */
646 if (fb
->_NumColorDrawBuffers
!= 1) {
647 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
651 /* Do this here, note core Mesa, since this function is called from
652 * many places within the driver.
654 if (ctx
->NewState
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
655 /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
656 _mesa_update_framebuffer(ctx
);
657 /* this updates the DrawBuffer's Width/Height if it's a FBO */
658 _mesa_update_draw_buffer_bounds(ctx
);
661 if (fb
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
662 /* this may occur when we're called by glBindFrameBuffer() during
663 * the process of someone setting up renderbuffers, etc.
665 /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
670 ;/* do something depthy/stencily TODO */
675 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
676 rrbColor
= radeon_renderbuffer(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
);
677 radeon
->front_cliprects
= GL_TRUE
;
679 rrbColor
= radeon_renderbuffer(fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
680 radeon
->front_cliprects
= GL_FALSE
;
683 /* user FBO in theory */
684 struct radeon_renderbuffer
*rrb
;
685 rrb
= radeon_renderbuffer(fb
->_ColorDrawBuffers
[0]);
687 offset
= rrb
->draw_offset
;
690 radeon
->constant_cliprect
= GL_TRUE
;
693 if (rrbColor
== NULL
)
694 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
696 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
699 if (fb
->_DepthBuffer
&& fb
->_DepthBuffer
->Wrapped
) {
700 rrbDepth
= radeon_renderbuffer(fb
->_DepthBuffer
->Wrapped
);
701 if (rrbDepth
&& rrbDepth
->bo
) {
702 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DEPTH_BUFFER
, GL_FALSE
);
704 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DEPTH_BUFFER
, GL_TRUE
);
707 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DEPTH_BUFFER
, GL_FALSE
);
711 if (fb
->_StencilBuffer
&& fb
->_StencilBuffer
->Wrapped
) {
712 rrbStencil
= radeon_renderbuffer(fb
->_DepthBuffer
->Wrapped
);
713 if (rrbStencil
&& rrbStencil
->bo
) {
714 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_STENCIL_BUFFER
, GL_FALSE
);
715 /* need to re-compute stencil hw state */
717 rrbDepth
= rrbStencil
;
719 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_STENCIL_BUFFER
, GL_TRUE
);
722 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_STENCIL_BUFFER
, GL_FALSE
);
723 if (ctx
->Driver
.Enable
!= NULL
)
724 ctx
->Driver
.Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
726 ctx
->NewState
|= _NEW_STENCIL
;
729 /* Update culling direction which changes depending on the
730 * orientation of the buffer:
732 if (ctx
->Driver
.FrontFace
)
733 ctx
->Driver
.FrontFace(ctx
, ctx
->Polygon
.FrontFace
);
735 ctx
->NewState
|= _NEW_POLYGON
;
738 * Update depth test state
740 if (ctx
->Driver
.Enable
) {
741 ctx
->Driver
.Enable(ctx
, GL_DEPTH_TEST
,
742 (ctx
->Depth
.Test
&& fb
->Visual
.depthBits
> 0));
743 ctx
->Driver
.Enable(ctx
, GL_STENCIL_TEST
,
744 (ctx
->Stencil
._Enabled
&& fb
->Visual
.stencilBits
> 0));
746 ctx
->NewState
|= (_NEW_DEPTH
| _NEW_STENCIL
);
749 radeon
->state
.depth
.rrb
= rrbDepth
;
750 radeon
->state
.color
.rrb
= rrbColor
;
751 radeon
->state
.color
.draw_offset
= offset
;
754 /* update viewport since it depends on window size */
755 if (ctx
->Driver
.Viewport
) {
756 ctx
->Driver
.Viewport(ctx
, ctx
->Viewport
.X
, ctx
->Viewport
.Y
,
757 ctx
->Viewport
.Width
, ctx
->Viewport
.Height
);
762 ctx
->NewState
|= _NEW_VIEWPORT
;
764 /* Set state we know depends on drawable parameters:
766 if (ctx
->Driver
.Scissor
)
767 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
768 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
769 radeon
->NewGLState
|= _NEW_SCISSOR
;
771 if (ctx
->Driver
.DepthRange
)
772 ctx
->Driver
.DepthRange(ctx
,
776 /* Update culling direction which changes depending on the
777 * orientation of the buffer:
779 if (ctx
->Driver
.FrontFace
)
780 ctx
->Driver
.FrontFace(ctx
, ctx
->Polygon
.FrontFace
);
782 ctx
->NewState
|= _NEW_POLYGON
;
786 * Called via glDrawBuffer.
788 void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
790 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
792 if (RADEON_DEBUG
& DEBUG_DRI
)
793 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
794 _mesa_lookup_enum_by_nr( mode
));
796 radeon_firevertices(radeon
); /* don't pipeline cliprect changes */
798 radeon_draw_buffer(ctx
, ctx
->DrawBuffer
);
801 void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
803 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
804 if (ctx
->ReadBuffer
== ctx
->DrawBuffer
) {
805 /* This will update FBO completeness status.
806 * A framebuffer will be incomplete if the GL_READ_BUFFER setting
807 * refers to a missing renderbuffer. Calling glReadBuffer can set
808 * that straight and can make the drawing buffer complete.
810 radeon_draw_buffer(ctx
, ctx
->DrawBuffer
);
815 /* Turn on/off page flipping according to the flags in the sarea:
817 void radeonUpdatePageFlipping(radeonContextPtr radeon
)
819 struct radeon_framebuffer
*rfb
= radeon
->dri
.drawable
->driverPrivate
;
821 rfb
->pf_active
= radeon
->sarea
->pfState
;
822 rfb
->pf_current_page
= radeon
->sarea
->pfCurrentPage
;
823 rfb
->pf_num_pages
= 2;
824 radeon_flip_renderbuffers(rfb
);
825 radeon_draw_buffer(radeon
->glCtx
, radeon
->glCtx
->DrawBuffer
);
828 void radeon_window_moved(radeonContextPtr radeon
)
830 if (!radeon
->radeonScreen
->driScreen
->dri2
.enabled
) {
831 radeonUpdatePageFlipping(radeon
);
833 radeonSetCliprects(radeon
);
836 void radeon_viewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei width
, GLsizei height
)
838 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
839 __DRIcontext
*driContext
= radeon
->dri
.context
;
840 void (*old_viewport
)(GLcontext
*ctx
, GLint x
, GLint y
,
841 GLsizei w
, GLsizei h
);
843 if (!driContext
->driScreenPriv
->dri2
.enabled
)
846 radeon_update_renderbuffers(driContext
, driContext
->driDrawablePriv
);
847 if (driContext
->driDrawablePriv
!= driContext
->driReadablePriv
)
848 radeon_update_renderbuffers(driContext
, driContext
->driReadablePriv
);
850 old_viewport
= ctx
->Driver
.Viewport
;
851 ctx
->Driver
.Viewport
= NULL
;
852 radeon
->dri
.drawable
= driContext
->driDrawablePriv
;
853 radeon_window_moved(radeon
);
854 radeon_draw_buffer(ctx
, radeon
->glCtx
->DrawBuffer
);
855 ctx
->Driver
.Viewport
= old_viewport
;
859 static void radeon_print_state_atom(radeonContextPtr radeon
, struct radeon_state_atom
*state
)
862 int dwords
= (*state
->check
)(radeon
->glCtx
, state
);
864 fprintf(stderr
, "emit %s %d/%d\n", state
->name
, state
->cmd_size
, dwords
);
866 if (RADEON_DEBUG
& DEBUG_VERBOSE
)
867 for (i
= 0 ; i
< dwords
; i
++)
868 fprintf(stderr
, "\t%s[%d]: %x\n", state
->name
, i
, state
->cmd
[i
]);
872 static INLINE
void radeonEmitAtoms(radeonContextPtr radeon
, GLboolean dirty
)
874 BATCH_LOCALS(radeon
);
875 struct radeon_state_atom
*atom
;
878 if (radeon
->vtbl
.pre_emit_atoms
)
879 radeon
->vtbl
.pre_emit_atoms(radeon
);
881 /* Emit actual atoms */
882 foreach(atom
, &radeon
->hw
.atomlist
) {
883 if ((atom
->dirty
|| radeon
->hw
.all_dirty
) == dirty
) {
884 dwords
= (*atom
->check
) (radeon
->glCtx
, atom
);
886 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_STATE
) {
887 radeon_print_state_atom(radeon
, atom
);
890 (*atom
->emit
)(radeon
->glCtx
, atom
);
892 BEGIN_BATCH_NO_AUTOSTATE(dwords
);
893 OUT_BATCH_TABLE(atom
->cmd
, dwords
);
896 atom
->dirty
= GL_FALSE
;
898 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_STATE
) {
899 fprintf(stderr
, " skip state %s\n",
909 void radeonEmitState(radeonContextPtr radeon
)
911 if (RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_PRIMS
))
912 fprintf(stderr
, "%s\n", __FUNCTION__
);
914 if (radeon
->vtbl
.pre_emit_state
)
915 radeon
->vtbl
.pre_emit_state(radeon
);
917 /* this code used to return here but now it emits zbs */
918 if (radeon
->cmdbuf
.cs
->cdw
&& !radeon
->hw
.is_dirty
&& !radeon
->hw
.all_dirty
)
921 /* To avoid going across the entire set of states multiple times, just check
922 * for enough space for the case of emitting all state, and inline the
923 * radeonAllocCmdBuf code here without all the checks.
925 rcommonEnsureCmdBufSpace(radeon
, radeon
->hw
.max_state_size
, __FUNCTION__
);
927 if (!radeon
->cmdbuf
.cs
->cdw
) {
928 if (RADEON_DEBUG
& DEBUG_STATE
)
929 fprintf(stderr
, "Begin reemit state\n");
931 radeonEmitAtoms(radeon
, GL_FALSE
);
934 if (RADEON_DEBUG
& DEBUG_STATE
)
935 fprintf(stderr
, "Begin dirty state\n");
937 radeonEmitAtoms(radeon
, GL_TRUE
);
938 radeon
->hw
.is_dirty
= GL_FALSE
;
939 radeon
->hw
.all_dirty
= GL_FALSE
;
944 void radeonFlush(GLcontext
*ctx
)
946 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
947 if (RADEON_DEBUG
& DEBUG_IOCTL
)
948 fprintf(stderr
, "%s %d\n", __FUNCTION__
, radeon
->cmdbuf
.cs
->cdw
);
950 if (radeon
->dma
.flush
)
951 radeon
->dma
.flush( ctx
);
953 radeonEmitState(radeon
);
955 if (radeon
->cmdbuf
.cs
->cdw
)
956 rcommonFlushCmdBuf(radeon
, __FUNCTION__
);
959 /* Make sure all commands have been sent to the hardware and have
960 * completed processing.
962 void radeonFinish(GLcontext
* ctx
)
964 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
965 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
970 if (radeon
->radeonScreen
->kernel_mm
) {
971 for (i
= 0; i
< fb
->_NumColorDrawBuffers
; i
++) {
972 struct radeon_renderbuffer
*rrb
;
973 rrb
= radeon_renderbuffer(fb
->_ColorDrawBuffers
[i
]);
975 radeon_bo_wait(rrb
->bo
);
978 struct radeon_renderbuffer
*rrb
;
979 rrb
= radeon_get_depthbuffer(radeon
);
981 radeon_bo_wait(rrb
->bo
);
983 } else if (radeon
->do_irqs
) {
984 LOCK_HARDWARE(radeon
);
985 radeonEmitIrqLocked(radeon
);
986 UNLOCK_HARDWARE(radeon
);
987 radeonWaitIrq(radeon
);
989 radeonWaitForIdle(radeon
);
995 * Send the current command buffer via ioctl to the hardware.
997 int rcommonFlushCmdBufLocked(radeonContextPtr rmesa
, const char *caller
)
1001 if (rmesa
->cmdbuf
.flushing
) {
1002 fprintf(stderr
, "Recursive call into r300FlushCmdBufLocked!\n");
1005 rmesa
->cmdbuf
.flushing
= 1;
1007 if (RADEON_DEBUG
& DEBUG_IOCTL
) {
1008 fprintf(stderr
, "%s from %s - %i cliprects\n",
1009 __FUNCTION__
, caller
, rmesa
->numClipRects
);
1012 if (rmesa
->cmdbuf
.cs
->cdw
) {
1013 ret
= radeon_cs_emit(rmesa
->cmdbuf
.cs
);
1014 rmesa
->hw
.all_dirty
= GL_TRUE
;
1016 radeon_cs_erase(rmesa
->cmdbuf
.cs
);
1017 rmesa
->cmdbuf
.flushing
= 0;
1021 int rcommonFlushCmdBuf(radeonContextPtr rmesa
, const char *caller
)
1025 radeonReleaseDmaRegion(rmesa
);
1027 LOCK_HARDWARE(rmesa
);
1028 ret
= rcommonFlushCmdBufLocked(rmesa
, caller
);
1029 UNLOCK_HARDWARE(rmesa
);
1032 fprintf(stderr
, "drmRadeonCmdBuffer: %d\n", ret
);
1040 * Make sure that enough space is available in the command buffer
1041 * by flushing if necessary.
1043 * \param dwords The number of dwords we need to be free on the command buffer
1045 void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa
, int dwords
, const char *caller
)
1047 if ((rmesa
->cmdbuf
.cs
->cdw
+ dwords
+ 128) > rmesa
->cmdbuf
.size
||
1048 radeon_cs_need_flush(rmesa
->cmdbuf
.cs
)) {
1049 rcommonFlushCmdBuf(rmesa
, caller
);
1053 void rcommonInitCmdBuf(radeonContextPtr rmesa
)
1056 /* Initialize command buffer */
1057 size
= 256 * driQueryOptioni(&rmesa
->optionCache
,
1058 "command_buffer_size");
1059 if (size
< 2 * rmesa
->hw
.max_state_size
) {
1060 size
= 2 * rmesa
->hw
.max_state_size
+ 65535;
1062 if (size
> 64 * 256)
1065 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
)) {
1066 fprintf(stderr
, "sizeof(drm_r300_cmd_header_t)=%zd\n",
1067 sizeof(drm_r300_cmd_header_t
));
1068 fprintf(stderr
, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n",
1069 sizeof(drm_radeon_cmd_buffer_t
));
1071 "Allocating %d bytes command buffer (max state is %d bytes)\n",
1072 size
* 4, rmesa
->hw
.max_state_size
* 4);
1075 if (rmesa
->radeonScreen
->kernel_mm
) {
1076 int fd
= rmesa
->radeonScreen
->driScreen
->fd
;
1077 rmesa
->cmdbuf
.csm
= radeon_cs_manager_gem_ctor(fd
);
1079 rmesa
->cmdbuf
.csm
= radeon_cs_manager_legacy_ctor(rmesa
);
1081 if (rmesa
->cmdbuf
.csm
== NULL
) {
1082 /* FIXME: fatal error */
1085 rmesa
->cmdbuf
.cs
= radeon_cs_create(rmesa
->cmdbuf
.csm
, size
);
1086 assert(rmesa
->cmdbuf
.cs
!= NULL
);
1087 rmesa
->cmdbuf
.size
= size
;
1089 if (!rmesa
->radeonScreen
->kernel_mm
) {
1090 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_VRAM
, rmesa
->radeonScreen
->texSize
[0]);
1091 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_GTT
, rmesa
->radeonScreen
->gartTextures
.size
);
1093 struct drm_radeon_gem_info mminfo
;
1095 if (!drmCommandWriteRead(rmesa
->dri
.fd
, DRM_RADEON_GEM_INFO
, &mminfo
, sizeof(mminfo
)))
1097 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_VRAM
, mminfo
.vram_visible
);
1098 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_GTT
, mminfo
.gart_size
);
1104 * Destroy the command buffer
1106 void rcommonDestroyCmdBuf(radeonContextPtr rmesa
)
1108 radeon_cs_destroy(rmesa
->cmdbuf
.cs
);
1109 if (rmesa
->radeonScreen
->driScreen
->dri2
.enabled
|| rmesa
->radeonScreen
->kernel_mm
) {
1110 radeon_cs_manager_gem_dtor(rmesa
->cmdbuf
.csm
);
1112 radeon_cs_manager_legacy_dtor(rmesa
->cmdbuf
.csm
);
1116 void rcommonBeginBatch(radeonContextPtr rmesa
, int n
,
1119 const char *function
,
1122 rcommonEnsureCmdBufSpace(rmesa
, n
, function
);
1123 if (!rmesa
->cmdbuf
.cs
->cdw
&& dostate
) {
1124 if (RADEON_DEBUG
& DEBUG_IOCTL
)
1125 fprintf(stderr
, "Reemit state after flush (from %s)\n", function
);
1126 radeonEmitState(rmesa
);
1128 radeon_cs_begin(rmesa
->cmdbuf
.cs
, n
, file
, function
, line
);
1130 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_IOCTL
)
1131 fprintf(stderr
, "BEGIN_BATCH(%d) at %d, from %s:%i\n",
1132 n
, rmesa
->cmdbuf
.cs
->cdw
, function
, line
);
1139 radeon_meta_set_passthrough_transform(radeonContextPtr radeon
)
1141 GLcontext
*ctx
= radeon
->glCtx
;
1143 radeon
->meta
.saved_vp_x
= ctx
->Viewport
.X
;
1144 radeon
->meta
.saved_vp_y
= ctx
->Viewport
.Y
;
1145 radeon
->meta
.saved_vp_width
= ctx
->Viewport
.Width
;
1146 radeon
->meta
.saved_vp_height
= ctx
->Viewport
.Height
;
1147 radeon
->meta
.saved_matrix_mode
= ctx
->Transform
.MatrixMode
;
1149 _mesa_Viewport(0, 0, ctx
->DrawBuffer
->Width
, ctx
->DrawBuffer
->Height
);
1151 _mesa_MatrixMode(GL_PROJECTION
);
1153 _mesa_LoadIdentity();
1154 _mesa_Ortho(0, ctx
->DrawBuffer
->Width
, 0, ctx
->DrawBuffer
->Height
, 1, -1);
1156 _mesa_MatrixMode(GL_MODELVIEW
);
1158 _mesa_LoadIdentity();
1162 radeon_meta_restore_transform(radeonContextPtr radeon
)
1164 _mesa_MatrixMode(GL_PROJECTION
);
1166 _mesa_MatrixMode(GL_MODELVIEW
);
1169 _mesa_MatrixMode(radeon
->meta
.saved_matrix_mode
);
1171 _mesa_Viewport(radeon
->meta
.saved_vp_x
, radeon
->meta
.saved_vp_y
,
1172 radeon
->meta
.saved_vp_width
, radeon
->meta
.saved_vp_height
);
1177 * Perform glClear where mask contains only color, depth, and/or stencil.
1179 * The implementation is based on calling into Mesa to set GL state and
1180 * performing normal triangle rendering. The intent of this path is to
1181 * have as generic a path as possible, so that any driver could make use of
1186 void radeon_clear_tris(GLcontext
*ctx
, GLbitfield mask
)
1188 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1189 GLfloat vertices
[4][3];
1190 GLfloat color
[4][4];
1192 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1194 GLboolean saved_fp_enable
= GL_FALSE
, saved_vp_enable
= GL_FALSE
;
1195 GLboolean saved_shader_program
= 0;
1196 unsigned int saved_active_texture
;
1198 assert((mask
& ~(TRI_CLEAR_COLOR_BITS
| BUFFER_BIT_DEPTH
|
1199 BUFFER_BIT_STENCIL
)) == 0);
1201 _mesa_PushAttrib(GL_COLOR_BUFFER_BIT
|
1203 GL_DEPTH_BUFFER_BIT
|
1205 GL_STENCIL_BUFFER_BIT
|
1208 _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT
);
1209 saved_active_texture
= ctx
->Texture
.CurrentUnit
;
1211 /* Disable existing GL state we don't want to apply to a clear. */
1212 _mesa_Disable(GL_ALPHA_TEST
);
1213 _mesa_Disable(GL_BLEND
);
1214 _mesa_Disable(GL_CULL_FACE
);
1215 _mesa_Disable(GL_FOG
);
1216 _mesa_Disable(GL_POLYGON_SMOOTH
);
1217 _mesa_Disable(GL_POLYGON_STIPPLE
);
1218 _mesa_Disable(GL_POLYGON_OFFSET_FILL
);
1219 _mesa_Disable(GL_LIGHTING
);
1220 _mesa_Disable(GL_CLIP_PLANE0
);
1221 _mesa_Disable(GL_CLIP_PLANE1
);
1222 _mesa_Disable(GL_CLIP_PLANE2
);
1223 _mesa_Disable(GL_CLIP_PLANE3
);
1224 _mesa_Disable(GL_CLIP_PLANE4
);
1225 _mesa_Disable(GL_CLIP_PLANE5
);
1226 if (ctx
->Extensions
.ARB_fragment_program
&& ctx
->FragmentProgram
.Enabled
) {
1227 saved_fp_enable
= GL_TRUE
;
1228 _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB
);
1230 if (ctx
->Extensions
.ARB_vertex_program
&& ctx
->VertexProgram
.Enabled
) {
1231 saved_vp_enable
= GL_TRUE
;
1232 _mesa_Disable(GL_VERTEX_PROGRAM_ARB
);
1234 if (ctx
->Extensions
.ARB_shader_objects
&& ctx
->Shader
.CurrentProgram
) {
1235 saved_shader_program
= ctx
->Shader
.CurrentProgram
->Name
;
1236 _mesa_UseProgramObjectARB(0);
1239 if (ctx
->Texture
._EnabledUnits
!= 0) {
1242 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1243 _mesa_ActiveTextureARB(GL_TEXTURE0
+ i
);
1244 _mesa_Disable(GL_TEXTURE_1D
);
1245 _mesa_Disable(GL_TEXTURE_2D
);
1246 _mesa_Disable(GL_TEXTURE_3D
);
1247 if (ctx
->Extensions
.ARB_texture_cube_map
)
1248 _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB
);
1249 if (ctx
->Extensions
.NV_texture_rectangle
)
1250 _mesa_Disable(GL_TEXTURE_RECTANGLE_NV
);
1251 if (ctx
->Extensions
.MESA_texture_array
) {
1252 _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT
);
1253 _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT
);
1258 radeon_meta_set_passthrough_transform(rmesa
);
1260 for (i
= 0; i
< 4; i
++) {
1261 color
[i
][0] = ctx
->Color
.ClearColor
[0];
1262 color
[i
][1] = ctx
->Color
.ClearColor
[1];
1263 color
[i
][2] = ctx
->Color
.ClearColor
[2];
1264 color
[i
][3] = ctx
->Color
.ClearColor
[3];
1267 /* convert clear Z from [0,1] to NDC coord in [-1,1] */
1269 dst_z
= -1.0 + 2.0 * ctx
->Depth
.Clear
;
1270 /* Prepare the vertices, which are the same regardless of which buffer we're
1273 vertices
[0][0] = fb
->_Xmin
;
1274 vertices
[0][1] = fb
->_Ymin
;
1275 vertices
[0][2] = dst_z
;
1276 vertices
[1][0] = fb
->_Xmax
;
1277 vertices
[1][1] = fb
->_Ymin
;
1278 vertices
[1][2] = dst_z
;
1279 vertices
[2][0] = fb
->_Xmax
;
1280 vertices
[2][1] = fb
->_Ymax
;
1281 vertices
[2][2] = dst_z
;
1282 vertices
[3][0] = fb
->_Xmin
;
1283 vertices
[3][1] = fb
->_Ymax
;
1284 vertices
[3][2] = dst_z
;
1286 _mesa_ColorPointer(4, GL_FLOAT
, 4 * sizeof(GLfloat
), &color
);
1287 _mesa_VertexPointer(3, GL_FLOAT
, 3 * sizeof(GLfloat
), &vertices
);
1288 _mesa_Enable(GL_COLOR_ARRAY
);
1289 _mesa_Enable(GL_VERTEX_ARRAY
);
1292 GLuint this_mask
= 0;
1295 color_bit
= _mesa_ffs(mask
& TRI_CLEAR_COLOR_BITS
);
1297 this_mask
|= (1 << (color_bit
- 1));
1299 /* Clear depth/stencil in the same pass as color. */
1300 this_mask
|= (mask
& (BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
));
1302 /* Select the current color buffer and use the color write mask if
1303 * we have one, otherwise don't write any color channels.
1305 if (this_mask
& BUFFER_BIT_FRONT_LEFT
)
1306 _mesa_DrawBuffer(GL_FRONT_LEFT
);
1307 else if (this_mask
& BUFFER_BIT_BACK_LEFT
)
1308 _mesa_DrawBuffer(GL_BACK_LEFT
);
1309 else if (color_bit
!= 0)
1310 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0
+
1311 (color_bit
- BUFFER_COLOR0
- 1));
1313 _mesa_ColorMask(GL_FALSE
, GL_FALSE
, GL_FALSE
, GL_FALSE
);
1315 /* Control writing of the depth clear value to depth. */
1316 if (this_mask
& BUFFER_BIT_DEPTH
) {
1317 _mesa_DepthFunc(GL_ALWAYS
);
1318 _mesa_DepthMask(GL_TRUE
);
1319 _mesa_Enable(GL_DEPTH_TEST
);
1321 _mesa_Disable(GL_DEPTH_TEST
);
1322 _mesa_DepthMask(GL_FALSE
);
1325 /* Control writing of the stencil clear value to stencil. */
1326 if (this_mask
& BUFFER_BIT_STENCIL
) {
1327 _mesa_Enable(GL_STENCIL_TEST
);
1328 _mesa_StencilOp(GL_REPLACE
, GL_REPLACE
, GL_REPLACE
);
1329 _mesa_StencilFuncSeparate(GL_FRONT
, GL_ALWAYS
, ctx
->Stencil
.Clear
,
1330 ctx
->Stencil
.WriteMask
[0]);
1332 _mesa_Disable(GL_STENCIL_TEST
);
1335 CALL_DrawArrays(ctx
->Exec
, (GL_TRIANGLE_FAN
, 0, 4));
1340 radeon_meta_restore_transform(rmesa
);
1342 _mesa_ActiveTextureARB(GL_TEXTURE0
+ saved_active_texture
);
1343 if (saved_fp_enable
)
1344 _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB
);
1345 if (saved_vp_enable
)
1346 _mesa_Enable(GL_VERTEX_PROGRAM_ARB
);
1348 if (saved_shader_program
)
1349 _mesa_UseProgramObjectARB(saved_shader_program
);
1351 _mesa_PopClientAttrib();