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/polygon.h"
66 #include "main/shaders.h"
67 #include "main/texstate.h"
68 #include "main/varray.h"
69 #include "glapi/dispatch.h"
70 #include "swrast/swrast.h"
71 #include "main/stencil.h"
72 #include "main/matrix.h"
73 #include "main/attrib.h"
74 #include "main/enable.h"
75 #include "main/viewport.h"
80 #include "radeon_common.h"
81 #include "radeon_bocs_wrapper.h"
82 #include "radeon_lock.h"
83 #include "radeon_drm.h"
84 #include "radeon_mipmap_tree.h"
86 #define DEBUG_CMDBUF 0
88 /* =============================================================
92 static GLboolean
intersect_rect(drm_clip_rect_t
* out
,
93 drm_clip_rect_t
* a
, drm_clip_rect_t
* b
)
104 if (out
->x1
>= out
->x2
)
106 if (out
->y1
>= out
->y2
)
111 void radeonRecalcScissorRects(radeonContextPtr radeon
)
113 drm_clip_rect_t
*out
;
116 /* Grow cliprect store?
118 if (radeon
->state
.scissor
.numAllocedClipRects
< radeon
->numClipRects
) {
119 while (radeon
->state
.scissor
.numAllocedClipRects
<
120 radeon
->numClipRects
) {
121 radeon
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
122 radeon
->state
.scissor
.numAllocedClipRects
*= 2;
125 if (radeon
->state
.scissor
.pClipRects
)
126 FREE(radeon
->state
.scissor
.pClipRects
);
128 radeon
->state
.scissor
.pClipRects
=
129 MALLOC(radeon
->state
.scissor
.numAllocedClipRects
*
130 sizeof(drm_clip_rect_t
));
132 if (radeon
->state
.scissor
.pClipRects
== NULL
) {
133 radeon
->state
.scissor
.numAllocedClipRects
= 0;
138 out
= radeon
->state
.scissor
.pClipRects
;
139 radeon
->state
.scissor
.numClipRects
= 0;
141 for (i
= 0; i
< radeon
->numClipRects
; i
++) {
142 if (intersect_rect(out
,
143 &radeon
->pClipRects
[i
],
144 &radeon
->state
.scissor
.rect
)) {
145 radeon
->state
.scissor
.numClipRects
++;
151 void radeon_get_cliprects(radeonContextPtr radeon
,
152 struct drm_clip_rect
**cliprects
,
153 unsigned int *num_cliprects
,
154 int *x_off
, int *y_off
)
156 __DRIdrawablePrivate
*dPriv
= radeon_get_drawable(radeon
);
157 struct radeon_framebuffer
*rfb
= dPriv
->driverPrivate
;
159 if (radeon
->constant_cliprect
) {
160 radeon
->fboRect
.x1
= 0;
161 radeon
->fboRect
.y1
= 0;
162 radeon
->fboRect
.x2
= radeon
->glCtx
->DrawBuffer
->Width
;
163 radeon
->fboRect
.y2
= radeon
->glCtx
->DrawBuffer
->Height
;
165 *cliprects
= &radeon
->fboRect
;
169 } else if (radeon
->front_cliprects
||
170 rfb
->pf_active
|| dPriv
->numBackClipRects
== 0) {
171 *cliprects
= dPriv
->pClipRects
;
172 *num_cliprects
= dPriv
->numClipRects
;
176 *num_cliprects
= dPriv
->numBackClipRects
;
177 *cliprects
= dPriv
->pBackClipRects
;
178 *x_off
= dPriv
->backX
;
179 *y_off
= dPriv
->backY
;
184 * Update cliprects and scissors.
186 void radeonSetCliprects(radeonContextPtr radeon
)
188 __DRIdrawablePrivate
*const drawable
= radeon_get_drawable(radeon
);
189 __DRIdrawablePrivate
*const readable
= radeon_get_readable(radeon
);
190 struct radeon_framebuffer
*const draw_rfb
= drawable
->driverPrivate
;
191 struct radeon_framebuffer
*const read_rfb
= readable
->driverPrivate
;
194 radeon_get_cliprects(radeon
, &radeon
->pClipRects
,
195 &radeon
->numClipRects
, &x_off
, &y_off
);
197 if ((draw_rfb
->base
.Width
!= drawable
->w
) ||
198 (draw_rfb
->base
.Height
!= drawable
->h
)) {
199 _mesa_resize_framebuffer(radeon
->glCtx
, &draw_rfb
->base
,
200 drawable
->w
, drawable
->h
);
201 draw_rfb
->base
.Initialized
= GL_TRUE
;
204 if (drawable
!= readable
) {
205 if ((read_rfb
->base
.Width
!= readable
->w
) ||
206 (read_rfb
->base
.Height
!= readable
->h
)) {
207 _mesa_resize_framebuffer(radeon
->glCtx
, &read_rfb
->base
,
208 readable
->w
, readable
->h
);
209 read_rfb
->base
.Initialized
= GL_TRUE
;
213 if (radeon
->state
.scissor
.enabled
)
214 radeonRecalcScissorRects(radeon
);
220 void radeonUpdateScissor( GLcontext
*ctx
)
222 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
224 if ( !ctx
->DrawBuffer
->Name
) {
225 __DRIdrawablePrivate
*dPriv
= radeon_get_drawable(rmesa
);
227 int x
= ctx
->Scissor
.X
;
228 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
229 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
230 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
232 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
233 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
234 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
235 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
237 rmesa
->state
.scissor
.rect
.x1
= ctx
->Scissor
.X
;
238 rmesa
->state
.scissor
.rect
.y1
= ctx
->Scissor
.Y
;
239 rmesa
->state
.scissor
.rect
.x2
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
;
240 rmesa
->state
.scissor
.rect
.y2
= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
;
243 radeonRecalcScissorRects( rmesa
);
246 /* =============================================================
250 void radeonScissor(GLcontext
* ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
252 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
253 if (ctx
->Scissor
.Enabled
) {
254 /* We don't pipeline cliprect changes */
255 radeon_firevertices(radeon
);
256 radeonUpdateScissor(ctx
);
261 /* ================================================================
262 * SwapBuffers with client-side throttling
265 static uint32_t radeonGetLastFrame(radeonContextPtr radeon
)
267 drm_radeon_getparam_t gp
;
271 gp
.param
= RADEON_PARAM_LAST_FRAME
;
272 gp
.value
= (int *)&frame
;
273 ret
= drmCommandWriteRead(radeon
->dri
.fd
, DRM_RADEON_GETPARAM
,
276 fprintf(stderr
, "%s: drmRadeonGetParam: %d\n", __FUNCTION__
,
284 uint32_t radeonGetAge(radeonContextPtr radeon
)
286 drm_radeon_getparam_t gp
;
290 gp
.param
= RADEON_PARAM_LAST_CLEAR
;
291 gp
.value
= (int *)&age
;
292 ret
= drmCommandWriteRead(radeon
->dri
.fd
, DRM_RADEON_GETPARAM
,
295 fprintf(stderr
, "%s: drmRadeonGetParam: %d\n", __FUNCTION__
,
303 static void radeonEmitIrqLocked(radeonContextPtr radeon
)
305 drm_radeon_irq_emit_t ie
;
308 ie
.irq_seq
= &radeon
->iw
.irq_seq
;
309 ret
= drmCommandWriteRead(radeon
->dri
.fd
, DRM_RADEON_IRQ_EMIT
,
312 fprintf(stderr
, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__
,
318 static void radeonWaitIrq(radeonContextPtr radeon
)
323 ret
= drmCommandWrite(radeon
->dri
.fd
, DRM_RADEON_IRQ_WAIT
,
324 &radeon
->iw
, sizeof(radeon
->iw
));
325 } while (ret
&& (errno
== EINTR
|| errno
== EBUSY
));
328 fprintf(stderr
, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__
,
334 static void radeonWaitForFrameCompletion(radeonContextPtr radeon
)
336 drm_radeon_sarea_t
*sarea
= radeon
->sarea
;
338 if (radeon
->do_irqs
) {
339 if (radeonGetLastFrame(radeon
) < sarea
->last_frame
) {
340 if (!radeon
->irqsEmitted
) {
341 while (radeonGetLastFrame(radeon
) <
344 UNLOCK_HARDWARE(radeon
);
345 radeonWaitIrq(radeon
);
346 LOCK_HARDWARE(radeon
);
348 radeon
->irqsEmitted
= 10;
351 if (radeon
->irqsEmitted
) {
352 radeonEmitIrqLocked(radeon
);
353 radeon
->irqsEmitted
--;
356 while (radeonGetLastFrame(radeon
) < sarea
->last_frame
) {
357 UNLOCK_HARDWARE(radeon
);
358 if (radeon
->do_usleeps
)
360 LOCK_HARDWARE(radeon
);
366 void radeonWaitForIdleLocked(radeonContextPtr radeon
)
372 ret
= drmCommandNone(radeon
->dri
.fd
, DRM_RADEON_CP_IDLE
);
375 } while (ret
&& ++i
< 100);
378 UNLOCK_HARDWARE(radeon
);
379 fprintf(stderr
, "Error: R300 timed out... exiting\n");
384 static void radeonWaitForIdle(radeonContextPtr radeon
)
386 if (!radeon
->radeonScreen
->driScreen
->dri2
.enabled
) {
387 LOCK_HARDWARE(radeon
);
388 radeonWaitForIdleLocked(radeon
);
389 UNLOCK_HARDWARE(radeon
);
393 static void radeon_flip_renderbuffers(struct radeon_framebuffer
*rfb
)
395 int current_page
= rfb
->pf_current_page
;
396 int next_page
= (current_page
+ 1) % rfb
->pf_num_pages
;
397 struct gl_renderbuffer
*tmp_rb
;
399 /* Exchange renderbuffers if necessary but make sure their
400 * reference counts are preserved.
402 if (rfb
->color_rb
[current_page
] &&
403 rfb
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
!=
404 &rfb
->color_rb
[current_page
]->base
) {
406 _mesa_reference_renderbuffer(&tmp_rb
,
407 rfb
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
);
408 tmp_rb
= &rfb
->color_rb
[current_page
]->base
;
409 _mesa_reference_renderbuffer(&rfb
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
, tmp_rb
);
410 _mesa_reference_renderbuffer(&tmp_rb
, NULL
);
413 if (rfb
->color_rb
[next_page
] &&
414 rfb
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
!=
415 &rfb
->color_rb
[next_page
]->base
) {
417 _mesa_reference_renderbuffer(&tmp_rb
,
418 rfb
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
419 tmp_rb
= &rfb
->color_rb
[next_page
]->base
;
420 _mesa_reference_renderbuffer(&rfb
->base
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
, tmp_rb
);
421 _mesa_reference_renderbuffer(&tmp_rb
, NULL
);
425 /* Copy the back color buffer to the front color buffer.
427 void radeonCopyBuffer( __DRIdrawablePrivate
*dPriv
,
428 const drm_clip_rect_t
*rect
)
430 radeonContextPtr rmesa
;
431 struct radeon_framebuffer
*rfb
;
435 assert(dPriv
->driContextPriv
);
436 assert(dPriv
->driContextPriv
->driverPrivate
);
438 rmesa
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
440 LOCK_HARDWARE(rmesa
);
442 rfb
= dPriv
->driverPrivate
;
444 if ( RADEON_DEBUG
& DEBUG_IOCTL
) {
445 fprintf( stderr
, "\n%s( %p )\n\n", __FUNCTION__
, (void *) rmesa
->glCtx
);
448 nbox
= dPriv
->numClipRects
; /* must be in locked region */
450 for ( i
= 0 ; i
< nbox
; ) {
451 GLint nr
= MIN2( i
+ RADEON_NR_SAREA_CLIPRECTS
, nbox
);
452 drm_clip_rect_t
*box
= dPriv
->pClipRects
;
453 drm_clip_rect_t
*b
= rmesa
->sarea
->boxes
;
456 for ( ; i
< nr
; i
++ ) {
462 if (rect
->x1
> b
->x1
)
464 if (rect
->y1
> b
->y1
)
466 if (rect
->x2
< b
->x2
)
468 if (rect
->y2
< b
->y2
)
471 if (b
->x1
>= b
->x2
|| b
->y1
>= b
->y2
)
478 rmesa
->sarea
->nbox
= n
;
483 ret
= drmCommandNone( rmesa
->dri
.fd
, DRM_RADEON_SWAP
);
486 fprintf( stderr
, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret
);
487 UNLOCK_HARDWARE( rmesa
);
492 UNLOCK_HARDWARE( rmesa
);
495 static int radeonScheduleSwap(__DRIdrawablePrivate
*dPriv
, GLboolean
*missed_target
)
497 radeonContextPtr rmesa
;
499 rmesa
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
500 radeon_firevertices(rmesa
);
502 LOCK_HARDWARE( rmesa
);
504 if (!dPriv
->numClipRects
) {
505 UNLOCK_HARDWARE(rmesa
);
506 usleep(10000); /* throttle invisible client 10ms */
510 radeonWaitForFrameCompletion(rmesa
);
512 UNLOCK_HARDWARE(rmesa
);
513 driWaitForVBlank(dPriv
, missed_target
);
518 static GLboolean
radeonPageFlip( __DRIdrawablePrivate
*dPriv
)
520 radeonContextPtr radeon
;
522 __DRIscreenPrivate
*psp
;
523 struct radeon_renderbuffer
*rrb
;
524 struct radeon_framebuffer
*rfb
;
527 assert(dPriv
->driContextPriv
);
528 assert(dPriv
->driContextPriv
->driverPrivate
);
530 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
531 rfb
= dPriv
->driverPrivate
;
532 rrb
= (void *)rfb
->base
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
534 psp
= dPriv
->driScreenPriv
;
536 LOCK_HARDWARE(radeon
);
538 if ( RADEON_DEBUG
& DEBUG_IOCTL
) {
539 fprintf(stderr
, "%s: pfCurrentPage: %d %d\n", __FUNCTION__
,
540 radeon
->sarea
->pfCurrentPage
, radeon
->sarea
->pfState
);
542 drm_clip_rect_t
*box
= dPriv
->pClipRects
;
543 drm_clip_rect_t
*b
= radeon
->sarea
->boxes
;
545 radeon
->sarea
->nbox
= 1;
547 ret
= drmCommandNone( radeon
->dri
.fd
, DRM_RADEON_FLIP
);
549 UNLOCK_HARDWARE(radeon
);
552 fprintf( stderr
, "DRM_RADEON_FLIP: return = %d\n", ret
);
559 rfb
->pf_current_page
= radeon
->sarea
->pfCurrentPage
;
560 radeon_flip_renderbuffers(rfb
);
561 radeon_draw_buffer(radeon
->glCtx
, &rfb
->base
);
568 * Swap front and back buffer.
570 void radeonSwapBuffers(__DRIdrawablePrivate
* dPriv
)
573 __DRIscreenPrivate
*psp
;
575 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
576 radeonContextPtr radeon
;
579 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
582 if (ctx
->Visual
.doubleBufferMode
) {
583 GLboolean missed_target
;
584 struct radeon_framebuffer
*rfb
= dPriv
->driverPrivate
;
585 _mesa_notifySwapBuffers(ctx
);/* flush pending rendering comands */
587 radeonScheduleSwap(dPriv
, &missed_target
);
589 if (rfb
->pf_active
) {
590 radeonPageFlip(dPriv
);
592 radeonCopyBuffer(dPriv
, NULL
);
595 psp
= dPriv
->driScreenPriv
;
598 (*psp
->systemTime
->getUST
)( & ust
);
599 if ( missed_target
) {
600 rfb
->swap_missed_count
++;
601 rfb
->swap_missed_ust
= ust
- rfb
->swap_ust
;
605 radeon
->hw
.all_dirty
= GL_TRUE
;
608 /* XXX this shouldn't be an error but we can't handle it for now */
609 _mesa_problem(NULL
, "%s: drawable has no context!",
614 void radeonCopySubBuffer(__DRIdrawablePrivate
* dPriv
,
615 int x
, int y
, int w
, int h
)
617 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
618 radeonContextPtr radeon
;
621 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
624 if (ctx
->Visual
.doubleBufferMode
) {
625 drm_clip_rect_t rect
;
626 rect
.x1
= x
+ dPriv
->x
;
627 rect
.y1
= (dPriv
->h
- y
- h
) + dPriv
->y
;
628 rect
.x2
= rect
.x1
+ w
;
629 rect
.y2
= rect
.y1
+ h
;
630 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
631 radeonCopyBuffer(dPriv
, &rect
);
634 /* XXX this shouldn't be an error but we can't handle it for now */
635 _mesa_problem(NULL
, "%s: drawable has no context!",
640 void radeon_draw_buffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
)
642 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
643 struct radeon_renderbuffer
*rrbDepth
= NULL
, *rrbStencil
= NULL
,
649 /* this can happen during the initial context initialization */
653 /* radeons only handle 1 color draw so far */
654 if (fb
->_NumColorDrawBuffers
!= 1) {
655 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
659 /* Do this here, note core Mesa, since this function is called from
660 * many places within the driver.
662 if (ctx
->NewState
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
663 /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
664 _mesa_update_framebuffer(ctx
);
665 /* this updates the DrawBuffer's Width/Height if it's a FBO */
666 _mesa_update_draw_buffer_bounds(ctx
);
669 if (fb
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
670 /* this may occur when we're called by glBindFrameBuffer() during
671 * the process of someone setting up renderbuffers, etc.
673 /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
678 ;/* do something depthy/stencily TODO */
683 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
684 rrbColor
= radeon_renderbuffer(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
);
685 radeon
->front_cliprects
= GL_TRUE
;
686 radeon
->front_buffer_dirty
= GL_TRUE
;
688 rrbColor
= radeon_renderbuffer(fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
689 radeon
->front_cliprects
= GL_FALSE
;
692 /* user FBO in theory */
693 struct radeon_renderbuffer
*rrb
;
694 rrb
= radeon_renderbuffer(fb
->_ColorDrawBuffers
[0]);
696 offset
= rrb
->draw_offset
;
699 radeon
->constant_cliprect
= GL_TRUE
;
702 if (rrbColor
== NULL
)
703 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
705 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
708 if (fb
->_DepthBuffer
&& fb
->_DepthBuffer
->Wrapped
) {
709 rrbDepth
= radeon_renderbuffer(fb
->_DepthBuffer
->Wrapped
);
710 if (rrbDepth
&& rrbDepth
->bo
) {
711 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DEPTH_BUFFER
, GL_FALSE
);
713 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DEPTH_BUFFER
, GL_TRUE
);
716 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_DEPTH_BUFFER
, GL_FALSE
);
720 if (fb
->_StencilBuffer
&& fb
->_StencilBuffer
->Wrapped
) {
721 rrbStencil
= radeon_renderbuffer(fb
->_StencilBuffer
->Wrapped
);
722 if (rrbStencil
&& rrbStencil
->bo
) {
723 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_STENCIL_BUFFER
, GL_FALSE
);
724 /* need to re-compute stencil hw state */
726 rrbDepth
= rrbStencil
;
728 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_STENCIL_BUFFER
, GL_TRUE
);
731 radeon
->vtbl
.fallback(ctx
, RADEON_FALLBACK_STENCIL_BUFFER
, GL_FALSE
);
732 if (ctx
->Driver
.Enable
!= NULL
)
733 ctx
->Driver
.Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
735 ctx
->NewState
|= _NEW_STENCIL
;
738 /* Update culling direction which changes depending on the
739 * orientation of the buffer:
741 if (ctx
->Driver
.FrontFace
)
742 ctx
->Driver
.FrontFace(ctx
, ctx
->Polygon
.FrontFace
);
744 ctx
->NewState
|= _NEW_POLYGON
;
747 * Update depth test state
749 if (ctx
->Driver
.Enable
) {
750 ctx
->Driver
.Enable(ctx
, GL_DEPTH_TEST
,
751 (ctx
->Depth
.Test
&& fb
->Visual
.depthBits
> 0));
752 /* Need to update the derived ctx->Stencil._Enabled first */
753 _mesa_update_stencil(ctx
);
754 ctx
->Driver
.Enable(ctx
, GL_STENCIL_TEST
,
755 (ctx
->Stencil
._Enabled
&& fb
->Visual
.stencilBits
> 0));
757 ctx
->NewState
|= (_NEW_DEPTH
| _NEW_STENCIL
);
760 _mesa_reference_renderbuffer(&radeon
->state
.depth
.rb
, &rrbDepth
->base
);
761 _mesa_reference_renderbuffer(&radeon
->state
.color
.rb
, &rrbColor
->base
);
762 radeon
->state
.color
.draw_offset
= offset
;
765 /* update viewport since it depends on window size */
766 if (ctx
->Driver
.Viewport
) {
767 ctx
->Driver
.Viewport(ctx
, ctx
->Viewport
.X
, ctx
->Viewport
.Y
,
768 ctx
->Viewport
.Width
, ctx
->Viewport
.Height
);
773 ctx
->NewState
|= _NEW_VIEWPORT
;
775 /* Set state we know depends on drawable parameters:
777 radeonUpdateScissor(ctx
);
778 radeon
->NewGLState
|= _NEW_SCISSOR
;
780 if (ctx
->Driver
.DepthRange
)
781 ctx
->Driver
.DepthRange(ctx
,
785 /* Update culling direction which changes depending on the
786 * orientation of the buffer:
788 if (ctx
->Driver
.FrontFace
)
789 ctx
->Driver
.FrontFace(ctx
, ctx
->Polygon
.FrontFace
);
791 ctx
->NewState
|= _NEW_POLYGON
;
795 * Called via glDrawBuffer.
797 void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
799 if (RADEON_DEBUG
& DEBUG_DRI
)
800 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
801 _mesa_lookup_enum_by_nr( mode
));
803 if (ctx
->DrawBuffer
->Name
== 0) {
804 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
806 const GLboolean was_front_buffer_rendering
=
807 radeon
->is_front_buffer_rendering
;
809 radeon
->is_front_buffer_rendering
= (mode
== GL_FRONT_LEFT
) ||
812 /* If we weren't front-buffer rendering before but we are now, make sure
813 * that the front-buffer has actually been allocated.
815 if (!was_front_buffer_rendering
&& radeon
->is_front_buffer_rendering
) {
816 radeon_update_renderbuffers(radeon
->dri
.context
,
817 radeon
->dri
.context
->driDrawablePriv
);
821 radeon_draw_buffer(ctx
, ctx
->DrawBuffer
);
824 void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
826 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
827 if (ctx
->ReadBuffer
== ctx
->DrawBuffer
) {
828 /* This will update FBO completeness status.
829 * A framebuffer will be incomplete if the GL_READ_BUFFER setting
830 * refers to a missing renderbuffer. Calling glReadBuffer can set
831 * that straight and can make the drawing buffer complete.
833 radeon_draw_buffer(ctx
, ctx
->DrawBuffer
);
838 /* Turn on/off page flipping according to the flags in the sarea:
840 void radeonUpdatePageFlipping(radeonContextPtr radeon
)
842 struct radeon_framebuffer
*rfb
= radeon_get_drawable(radeon
)->driverPrivate
;
844 rfb
->pf_active
= radeon
->sarea
->pfState
;
845 rfb
->pf_current_page
= radeon
->sarea
->pfCurrentPage
;
846 rfb
->pf_num_pages
= 2;
847 radeon_flip_renderbuffers(rfb
);
848 radeon_draw_buffer(radeon
->glCtx
, radeon
->glCtx
->DrawBuffer
);
851 void radeon_window_moved(radeonContextPtr radeon
)
853 if (!radeon
->radeonScreen
->driScreen
->dri2
.enabled
) {
854 radeonUpdatePageFlipping(radeon
);
856 radeonSetCliprects(radeon
);
859 void radeon_viewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei width
, GLsizei height
)
861 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
862 __DRIcontext
*driContext
= radeon
->dri
.context
;
863 void (*old_viewport
)(GLcontext
*ctx
, GLint x
, GLint y
,
864 GLsizei w
, GLsizei h
);
866 if (!driContext
->driScreenPriv
->dri2
.enabled
)
870 radeon_update_renderbuffers(driContext
, driContext
->driDrawablePriv
);
871 if (driContext
->driDrawablePriv
!= driContext
->driReadablePriv
)
872 radeon_update_renderbuffers(driContext
, driContext
->driReadablePriv
);
874 old_viewport
= ctx
->Driver
.Viewport
;
875 ctx
->Driver
.Viewport
= NULL
;
876 radeon_window_moved(radeon
);
877 radeon_draw_buffer(ctx
, radeon
->glCtx
->DrawBuffer
);
878 ctx
->Driver
.Viewport
= old_viewport
;
881 static void radeon_print_state_atom(radeonContextPtr radeon
, struct radeon_state_atom
*state
)
884 int dwords
= (*state
->check
) (radeon
->glCtx
, state
);
885 drm_r300_cmd_header_t cmd
;
887 fprintf(stderr
, " emit %s %d/%d\n", state
->name
, dwords
, state
->cmd_size
);
889 if (RADEON_DEBUG
& DEBUG_VERBOSE
) {
890 for (i
= 0; i
< dwords
;) {
891 cmd
= *((drm_r300_cmd_header_t
*) &state
->cmd
[i
]);
892 reg
= (cmd
.packet0
.reghi
<< 8) | cmd
.packet0
.reglo
;
893 fprintf(stderr
, " %s[%d]: cmdpacket0 (first reg=0x%04x, count=%d)\n",
894 state
->name
, i
, reg
, cmd
.packet0
.count
);
896 for (j
= 0; j
< cmd
.packet0
.count
&& i
< dwords
; j
++) {
897 fprintf(stderr
, " %s[%d]: 0x%04x = %08x\n",
898 state
->name
, i
, reg
, state
->cmd
[i
]);
906 static void radeon_print_state_atom_kmm(radeonContextPtr radeon
, struct radeon_state_atom
*state
)
908 int i
, j
, reg
, count
;
909 int dwords
= (*state
->check
) (radeon
->glCtx
, state
);
912 fprintf(stderr
, " emit %s %d/%d\n", state
->name
, dwords
, state
->cmd_size
);
914 if (RADEON_DEBUG
& DEBUG_VERBOSE
) {
915 for (i
= 0; i
< dwords
;) {
916 packet0
= state
->cmd
[i
];
917 reg
= (packet0
& 0x1FFF) << 2;
918 count
= ((packet0
& 0x3FFF0000) >> 16) + 1;
919 fprintf(stderr
, " %s[%d]: cmdpacket0 (first reg=0x%04x, count=%d)\n",
920 state
->name
, i
, reg
, count
);
922 for (j
= 0; j
< count
&& i
< dwords
; j
++) {
923 fprintf(stderr
, " %s[%d]: 0x%04x = %08x\n",
924 state
->name
, i
, reg
, state
->cmd
[i
]);
932 static INLINE
void radeonEmitAtoms(radeonContextPtr radeon
, GLboolean dirty
)
934 BATCH_LOCALS(radeon
);
935 struct radeon_state_atom
*atom
;
938 if (radeon
->vtbl
.pre_emit_atoms
)
939 radeon
->vtbl
.pre_emit_atoms(radeon
);
941 /* Emit actual atoms */
942 foreach(atom
, &radeon
->hw
.atomlist
) {
943 if ((atom
->dirty
|| radeon
->hw
.all_dirty
) == dirty
) {
944 dwords
= (*atom
->check
) (radeon
->glCtx
, atom
);
946 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_STATE
) {
947 if (radeon
->radeonScreen
->kernel_mm
)
948 radeon_print_state_atom_kmm(radeon
, atom
);
950 radeon_print_state_atom(radeon
, atom
);
953 (*atom
->emit
)(radeon
->glCtx
, atom
);
955 BEGIN_BATCH_NO_AUTOSTATE(dwords
);
956 OUT_BATCH_TABLE(atom
->cmd
, dwords
);
959 atom
->dirty
= GL_FALSE
;
961 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_STATE
) {
962 fprintf(stderr
, " skip state %s\n",
972 static GLboolean
radeon_revalidate_bos(GLcontext
*ctx
)
974 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
977 ret
= radeon_cs_space_check(radeon
->cmdbuf
.cs
);
978 if (ret
== RADEON_CS_SPACE_FLUSH
)
983 void radeonEmitState(radeonContextPtr radeon
)
985 if (RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_PRIMS
))
986 fprintf(stderr
, "%s\n", __FUNCTION__
);
988 if (radeon
->vtbl
.pre_emit_state
)
989 radeon
->vtbl
.pre_emit_state(radeon
);
991 /* this code used to return here but now it emits zbs */
992 if (radeon
->cmdbuf
.cs
->cdw
&& !radeon
->hw
.is_dirty
&& !radeon
->hw
.all_dirty
)
995 /* To avoid going across the entire set of states multiple times, just check
996 * for enough space for the case of emitting all state, and inline the
997 * radeonAllocCmdBuf code here without all the checks.
999 rcommonEnsureCmdBufSpace(radeon
, radeon
->hw
.max_state_size
, __FUNCTION__
);
1001 if (!radeon
->cmdbuf
.cs
->cdw
) {
1002 if (RADEON_DEBUG
& DEBUG_STATE
)
1003 fprintf(stderr
, "Begin reemit state\n");
1005 radeonEmitAtoms(radeon
, GL_FALSE
);
1008 if (RADEON_DEBUG
& DEBUG_STATE
)
1009 fprintf(stderr
, "Begin dirty state\n");
1011 radeonEmitAtoms(radeon
, GL_TRUE
);
1012 radeon
->hw
.is_dirty
= GL_FALSE
;
1013 radeon
->hw
.all_dirty
= GL_FALSE
;
1018 void radeonFlush(GLcontext
*ctx
)
1020 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
1021 if (RADEON_DEBUG
& DEBUG_IOCTL
)
1022 fprintf(stderr
, "%s %d\n", __FUNCTION__
, radeon
->cmdbuf
.cs
->cdw
);
1024 /* okay if we have no cmds in the buffer &&
1025 we have no DMA flush &&
1026 we have no DMA buffer allocated.
1027 then no point flushing anything at all.
1029 if (!radeon
->dma
.flush
&& !radeon
->cmdbuf
.cs
->cdw
&& !radeon
->dma
.current
)
1032 if (radeon
->dma
.flush
)
1033 radeon
->dma
.flush( ctx
);
1035 radeonEmitState(radeon
);
1037 if (radeon
->cmdbuf
.cs
->cdw
)
1038 rcommonFlushCmdBuf(radeon
, __FUNCTION__
);
1040 if ((ctx
->DrawBuffer
->Name
== 0) && radeon
->front_buffer_dirty
) {
1041 __DRIscreen
*const screen
= radeon
->radeonScreen
->driScreen
;
1043 if (screen
->dri2
.loader
&& (screen
->dri2
.loader
->base
.version
>= 2)
1044 && (screen
->dri2
.loader
->flushFrontBuffer
!= NULL
)) {
1045 __DRIdrawablePrivate
* drawable
= radeon_get_drawable(radeon
);
1046 (*screen
->dri2
.loader
->flushFrontBuffer
)(drawable
, drawable
->loaderPrivate
);
1048 /* Only clear the dirty bit if front-buffer rendering is no longer
1049 * enabled. This is done so that the dirty bit can only be set in
1050 * glDrawBuffer. Otherwise the dirty bit would have to be set at
1051 * each of N places that do rendering. This has worse performances,
1052 * but it is much easier to get correct.
1054 if (radeon
->is_front_buffer_rendering
) {
1055 radeon
->front_buffer_dirty
= GL_FALSE
;
1061 /* Make sure all commands have been sent to the hardware and have
1062 * completed processing.
1064 void radeonFinish(GLcontext
* ctx
)
1066 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
1067 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1072 if (radeon
->radeonScreen
->kernel_mm
) {
1073 for (i
= 0; i
< fb
->_NumColorDrawBuffers
; i
++) {
1074 struct radeon_renderbuffer
*rrb
;
1075 rrb
= radeon_renderbuffer(fb
->_ColorDrawBuffers
[i
]);
1077 radeon_bo_wait(rrb
->bo
);
1080 struct radeon_renderbuffer
*rrb
;
1081 rrb
= radeon_get_depthbuffer(radeon
);
1083 radeon_bo_wait(rrb
->bo
);
1085 } else if (radeon
->do_irqs
) {
1086 LOCK_HARDWARE(radeon
);
1087 radeonEmitIrqLocked(radeon
);
1088 UNLOCK_HARDWARE(radeon
);
1089 radeonWaitIrq(radeon
);
1091 radeonWaitForIdle(radeon
);
1097 * Send the current command buffer via ioctl to the hardware.
1099 int rcommonFlushCmdBufLocked(radeonContextPtr rmesa
, const char *caller
)
1103 if (rmesa
->cmdbuf
.flushing
) {
1104 fprintf(stderr
, "Recursive call into r300FlushCmdBufLocked!\n");
1107 rmesa
->cmdbuf
.flushing
= 1;
1109 if (RADEON_DEBUG
& DEBUG_IOCTL
) {
1110 fprintf(stderr
, "%s from %s - %i cliprects\n",
1111 __FUNCTION__
, caller
, rmesa
->numClipRects
);
1114 if (rmesa
->cmdbuf
.cs
->cdw
) {
1115 ret
= radeon_cs_emit(rmesa
->cmdbuf
.cs
);
1116 rmesa
->hw
.all_dirty
= GL_TRUE
;
1118 radeon_cs_erase(rmesa
->cmdbuf
.cs
);
1119 rmesa
->cmdbuf
.flushing
= 0;
1121 if (radeon_revalidate_bos(rmesa
->glCtx
) == GL_FALSE
) {
1122 fprintf(stderr
,"failed to revalidate buffers\n");
1128 int rcommonFlushCmdBuf(radeonContextPtr rmesa
, const char *caller
)
1132 radeonReleaseDmaRegion(rmesa
);
1134 LOCK_HARDWARE(rmesa
);
1135 ret
= rcommonFlushCmdBufLocked(rmesa
, caller
);
1136 UNLOCK_HARDWARE(rmesa
);
1139 fprintf(stderr
, "drmRadeonCmdBuffer: %d\n", ret
);
1147 * Make sure that enough space is available in the command buffer
1148 * by flushing if necessary.
1150 * \param dwords The number of dwords we need to be free on the command buffer
1152 void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa
, int dwords
, const char *caller
)
1154 if ((rmesa
->cmdbuf
.cs
->cdw
+ dwords
+ 128) > rmesa
->cmdbuf
.size
||
1155 radeon_cs_need_flush(rmesa
->cmdbuf
.cs
)) {
1156 rcommonFlushCmdBuf(rmesa
, caller
);
1160 void rcommonInitCmdBuf(radeonContextPtr rmesa
)
1163 /* Initialize command buffer */
1164 size
= 256 * driQueryOptioni(&rmesa
->optionCache
,
1165 "command_buffer_size");
1166 if (size
< 2 * rmesa
->hw
.max_state_size
) {
1167 size
= 2 * rmesa
->hw
.max_state_size
+ 65535;
1169 if (size
> 64 * 256)
1172 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
)) {
1173 fprintf(stderr
, "sizeof(drm_r300_cmd_header_t)=%zd\n",
1174 sizeof(drm_r300_cmd_header_t
));
1175 fprintf(stderr
, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n",
1176 sizeof(drm_radeon_cmd_buffer_t
));
1178 "Allocating %d bytes command buffer (max state is %d bytes)\n",
1179 size
* 4, rmesa
->hw
.max_state_size
* 4);
1182 if (rmesa
->radeonScreen
->kernel_mm
) {
1183 int fd
= rmesa
->radeonScreen
->driScreen
->fd
;
1184 rmesa
->cmdbuf
.csm
= radeon_cs_manager_gem_ctor(fd
);
1186 rmesa
->cmdbuf
.csm
= radeon_cs_manager_legacy_ctor(rmesa
);
1188 if (rmesa
->cmdbuf
.csm
== NULL
) {
1189 /* FIXME: fatal error */
1192 rmesa
->cmdbuf
.cs
= radeon_cs_create(rmesa
->cmdbuf
.csm
, size
);
1193 assert(rmesa
->cmdbuf
.cs
!= NULL
);
1194 rmesa
->cmdbuf
.size
= size
;
1196 radeon_cs_space_set_flush(rmesa
->cmdbuf
.cs
,
1197 (void (*)(void *))radeonFlush
, rmesa
->glCtx
);
1199 if (!rmesa
->radeonScreen
->kernel_mm
) {
1200 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_VRAM
, rmesa
->radeonScreen
->texSize
[0]);
1201 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_GTT
, rmesa
->radeonScreen
->gartTextures
.size
);
1203 struct drm_radeon_gem_info mminfo
= { 0 };
1205 if (!drmCommandWriteRead(rmesa
->dri
.fd
, DRM_RADEON_GEM_INFO
, &mminfo
, sizeof(mminfo
)))
1207 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_VRAM
, mminfo
.vram_visible
);
1208 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_GTT
, mminfo
.gart_size
);
1214 * Destroy the command buffer
1216 void rcommonDestroyCmdBuf(radeonContextPtr rmesa
)
1218 radeon_cs_destroy(rmesa
->cmdbuf
.cs
);
1219 if (rmesa
->radeonScreen
->driScreen
->dri2
.enabled
|| rmesa
->radeonScreen
->kernel_mm
) {
1220 radeon_cs_manager_gem_dtor(rmesa
->cmdbuf
.csm
);
1222 radeon_cs_manager_legacy_dtor(rmesa
->cmdbuf
.csm
);
1226 void rcommonBeginBatch(radeonContextPtr rmesa
, int n
,
1229 const char *function
,
1232 rcommonEnsureCmdBufSpace(rmesa
, n
, function
);
1233 if (!rmesa
->cmdbuf
.cs
->cdw
&& dostate
) {
1234 if (RADEON_DEBUG
& DEBUG_IOCTL
)
1235 fprintf(stderr
, "Reemit state after flush (from %s)\n", function
);
1236 radeonEmitState(rmesa
);
1238 radeon_cs_begin(rmesa
->cmdbuf
.cs
, n
, file
, function
, line
);
1240 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_IOCTL
)
1241 fprintf(stderr
, "BEGIN_BATCH(%d) at %d, from %s:%i\n",
1242 n
, rmesa
->cmdbuf
.cs
->cdw
, function
, line
);
1249 radeon_meta_set_passthrough_transform(radeonContextPtr radeon
)
1251 GLcontext
*ctx
= radeon
->glCtx
;
1253 radeon
->meta
.saved_vp_x
= ctx
->Viewport
.X
;
1254 radeon
->meta
.saved_vp_y
= ctx
->Viewport
.Y
;
1255 radeon
->meta
.saved_vp_width
= ctx
->Viewport
.Width
;
1256 radeon
->meta
.saved_vp_height
= ctx
->Viewport
.Height
;
1257 radeon
->meta
.saved_matrix_mode
= ctx
->Transform
.MatrixMode
;
1259 _mesa_Viewport(0, 0, ctx
->DrawBuffer
->Width
, ctx
->DrawBuffer
->Height
);
1261 _mesa_MatrixMode(GL_PROJECTION
);
1263 _mesa_LoadIdentity();
1264 _mesa_Ortho(0, ctx
->DrawBuffer
->Width
, 0, ctx
->DrawBuffer
->Height
, 1, -1);
1266 _mesa_MatrixMode(GL_MODELVIEW
);
1268 _mesa_LoadIdentity();
1272 radeon_meta_restore_transform(radeonContextPtr radeon
)
1274 _mesa_MatrixMode(GL_PROJECTION
);
1276 _mesa_MatrixMode(GL_MODELVIEW
);
1279 _mesa_MatrixMode(radeon
->meta
.saved_matrix_mode
);
1281 _mesa_Viewport(radeon
->meta
.saved_vp_x
, radeon
->meta
.saved_vp_y
,
1282 radeon
->meta
.saved_vp_width
, radeon
->meta
.saved_vp_height
);
1287 * Perform glClear where mask contains only color, depth, and/or stencil.
1289 * The implementation is based on calling into Mesa to set GL state and
1290 * performing normal triangle rendering. The intent of this path is to
1291 * have as generic a path as possible, so that any driver could make use of
1296 void radeon_clear_tris(GLcontext
*ctx
, GLbitfield mask
)
1298 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1299 GLfloat vertices
[4][3];
1300 GLfloat color
[4][4];
1302 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1304 GLboolean saved_fp_enable
= GL_FALSE
, saved_vp_enable
= GL_FALSE
;
1305 GLboolean saved_shader_program
= 0;
1306 unsigned int saved_active_texture
;
1308 assert((mask
& ~(TRI_CLEAR_COLOR_BITS
| BUFFER_BIT_DEPTH
|
1309 BUFFER_BIT_STENCIL
)) == 0);
1311 _mesa_PushAttrib(GL_COLOR_BUFFER_BIT
|
1313 GL_DEPTH_BUFFER_BIT
|
1316 GL_STENCIL_BUFFER_BIT
|
1319 _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT
);
1320 saved_active_texture
= ctx
->Texture
.CurrentUnit
;
1322 /* Disable existing GL state we don't want to apply to a clear. */
1323 _mesa_Disable(GL_ALPHA_TEST
);
1324 _mesa_Disable(GL_BLEND
);
1325 _mesa_Disable(GL_CULL_FACE
);
1326 _mesa_Disable(GL_FOG
);
1327 _mesa_Disable(GL_POLYGON_SMOOTH
);
1328 _mesa_Disable(GL_POLYGON_STIPPLE
);
1329 _mesa_Disable(GL_POLYGON_OFFSET_FILL
);
1330 _mesa_Disable(GL_LIGHTING
);
1331 _mesa_Disable(GL_CLIP_PLANE0
);
1332 _mesa_Disable(GL_CLIP_PLANE1
);
1333 _mesa_Disable(GL_CLIP_PLANE2
);
1334 _mesa_Disable(GL_CLIP_PLANE3
);
1335 _mesa_Disable(GL_CLIP_PLANE4
);
1336 _mesa_Disable(GL_CLIP_PLANE5
);
1337 _mesa_PolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
1338 if (ctx
->Extensions
.ARB_fragment_program
&& ctx
->FragmentProgram
.Enabled
) {
1339 saved_fp_enable
= GL_TRUE
;
1340 _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB
);
1342 if (ctx
->Extensions
.ARB_vertex_program
&& ctx
->VertexProgram
.Enabled
) {
1343 saved_vp_enable
= GL_TRUE
;
1344 _mesa_Disable(GL_VERTEX_PROGRAM_ARB
);
1346 if (ctx
->Extensions
.ARB_shader_objects
&& ctx
->Shader
.CurrentProgram
) {
1347 saved_shader_program
= ctx
->Shader
.CurrentProgram
->Name
;
1348 _mesa_UseProgramObjectARB(0);
1351 if (ctx
->Texture
._EnabledUnits
!= 0) {
1354 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1355 _mesa_ActiveTextureARB(GL_TEXTURE0
+ i
);
1356 _mesa_Disable(GL_TEXTURE_1D
);
1357 _mesa_Disable(GL_TEXTURE_2D
);
1358 _mesa_Disable(GL_TEXTURE_3D
);
1359 if (ctx
->Extensions
.ARB_texture_cube_map
)
1360 _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB
);
1361 if (ctx
->Extensions
.NV_texture_rectangle
)
1362 _mesa_Disable(GL_TEXTURE_RECTANGLE_NV
);
1363 if (ctx
->Extensions
.MESA_texture_array
) {
1364 _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT
);
1365 _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT
);
1370 #if FEATURE_ARB_vertex_buffer_object
1371 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB
, 0);
1372 _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, 0);
1375 radeon_meta_set_passthrough_transform(rmesa
);
1377 for (i
= 0; i
< 4; i
++) {
1378 color
[i
][0] = ctx
->Color
.ClearColor
[0];
1379 color
[i
][1] = ctx
->Color
.ClearColor
[1];
1380 color
[i
][2] = ctx
->Color
.ClearColor
[2];
1381 color
[i
][3] = ctx
->Color
.ClearColor
[3];
1384 /* convert clear Z from [0,1] to NDC coord in [-1,1] */
1386 dst_z
= -1.0 + 2.0 * ctx
->Depth
.Clear
;
1387 /* Prepare the vertices, which are the same regardless of which buffer we're
1390 vertices
[0][0] = fb
->_Xmin
;
1391 vertices
[0][1] = fb
->_Ymin
;
1392 vertices
[0][2] = dst_z
;
1393 vertices
[1][0] = fb
->_Xmax
;
1394 vertices
[1][1] = fb
->_Ymin
;
1395 vertices
[1][2] = dst_z
;
1396 vertices
[2][0] = fb
->_Xmax
;
1397 vertices
[2][1] = fb
->_Ymax
;
1398 vertices
[2][2] = dst_z
;
1399 vertices
[3][0] = fb
->_Xmin
;
1400 vertices
[3][1] = fb
->_Ymax
;
1401 vertices
[3][2] = dst_z
;
1403 _mesa_ColorPointer(4, GL_FLOAT
, 4 * sizeof(GLfloat
), &color
);
1404 _mesa_VertexPointer(3, GL_FLOAT
, 3 * sizeof(GLfloat
), &vertices
);
1405 _mesa_Enable(GL_COLOR_ARRAY
);
1406 _mesa_Enable(GL_VERTEX_ARRAY
);
1409 GLuint this_mask
= 0;
1412 color_bit
= _mesa_ffs(mask
& TRI_CLEAR_COLOR_BITS
);
1414 this_mask
|= (1 << (color_bit
- 1));
1416 /* Clear depth/stencil in the same pass as color. */
1417 this_mask
|= (mask
& (BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
));
1419 /* Select the current color buffer and use the color write mask if
1420 * we have one, otherwise don't write any color channels.
1422 if (this_mask
& BUFFER_BIT_FRONT_LEFT
)
1423 _mesa_DrawBuffer(GL_FRONT_LEFT
);
1424 else if (this_mask
& BUFFER_BIT_BACK_LEFT
)
1425 _mesa_DrawBuffer(GL_BACK_LEFT
);
1426 else if (color_bit
!= 0)
1427 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0
+
1428 (color_bit
- BUFFER_COLOR0
- 1));
1430 _mesa_ColorMask(GL_FALSE
, GL_FALSE
, GL_FALSE
, GL_FALSE
);
1432 /* Control writing of the depth clear value to depth. */
1433 if (this_mask
& BUFFER_BIT_DEPTH
) {
1434 _mesa_DepthFunc(GL_ALWAYS
);
1435 _mesa_DepthMask(GL_TRUE
);
1436 _mesa_Enable(GL_DEPTH_TEST
);
1438 _mesa_Disable(GL_DEPTH_TEST
);
1439 _mesa_DepthMask(GL_FALSE
);
1442 /* Control writing of the stencil clear value to stencil. */
1443 if (this_mask
& BUFFER_BIT_STENCIL
) {
1444 _mesa_Enable(GL_STENCIL_TEST
);
1445 _mesa_StencilOp(GL_REPLACE
, GL_REPLACE
, GL_REPLACE
);
1446 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK
, GL_ALWAYS
, ctx
->Stencil
.Clear
,
1447 ctx
->Stencil
.WriteMask
[0]);
1449 _mesa_Disable(GL_STENCIL_TEST
);
1452 CALL_DrawArrays(ctx
->Exec
, (GL_TRIANGLE_FAN
, 0, 4));
1457 radeon_meta_restore_transform(rmesa
);
1459 _mesa_ActiveTextureARB(GL_TEXTURE0
+ saved_active_texture
);
1460 if (saved_fp_enable
)
1461 _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB
);
1462 if (saved_vp_enable
)
1463 _mesa_Enable(GL_VERTEX_PROGRAM_ARB
);
1465 if (saved_shader_program
)
1466 _mesa_UseProgramObjectARB(saved_shader_program
);
1468 _mesa_PopClientAttrib();