1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.8 2002/12/16 16:18:58 dawes Exp $ */
2 /**************************************************************************
4 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Gareth Hughes <gareth@valinux.com>
33 * Keith Whitwell <keith@tungstengraphics.com>
38 #include "api_arrayelt.h"
44 #include "array_cache/acache.h"
46 #include "tnl/t_pipeline.h"
47 #include "swrast_setup/swrast_setup.h"
49 #include "radeon_context.h"
50 #include "radeon_ioctl.h"
51 #include "radeon_state.h"
52 #include "radeon_tcl.h"
53 #include "radeon_tex.h"
54 #include "radeon_swtcl.h"
55 #include "radeon_vtxfmt.h"
56 #include "drirenderbuffer.h"
58 /* =============================================================
62 static void radeonAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
64 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
65 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
68 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
70 RADEON_STATECHANGE( rmesa
, ctx
);
72 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
73 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
77 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
80 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
83 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
86 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
89 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
92 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
95 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
98 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
102 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
105 static void radeonBlendEquationSeparate( GLcontext
*ctx
,
106 GLenum modeRGB
, GLenum modeA
)
108 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
109 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
110 GLboolean fallback
= GL_FALSE
;
112 assert( modeRGB
== modeA
);
117 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
120 case GL_FUNC_SUBTRACT
:
121 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
125 if (ctx
->Color
.BlendEnabled
)
128 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
132 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
134 RADEON_STATECHANGE( rmesa
, ctx
);
135 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
136 if ( ctx
->Color
._LogicOpEnabled
) {
137 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
139 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
144 static void radeonBlendFuncSeparate( GLcontext
*ctx
,
145 GLenum sfactorRGB
, GLenum dfactorRGB
,
146 GLenum sfactorA
, GLenum dfactorA
)
148 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
149 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
150 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
151 GLboolean fallback
= GL_FALSE
;
153 switch ( ctx
->Color
.BlendSrcRGB
) {
155 b
|= RADEON_SRC_BLEND_GL_ZERO
;
158 b
|= RADEON_SRC_BLEND_GL_ONE
;
161 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
163 case GL_ONE_MINUS_DST_COLOR
:
164 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
167 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
169 case GL_ONE_MINUS_SRC_COLOR
:
170 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
173 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
175 case GL_ONE_MINUS_SRC_ALPHA
:
176 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
179 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
181 case GL_ONE_MINUS_DST_ALPHA
:
182 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
184 case GL_SRC_ALPHA_SATURATE
:
185 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
187 case GL_CONSTANT_COLOR
:
188 case GL_ONE_MINUS_CONSTANT_COLOR
:
189 case GL_CONSTANT_ALPHA
:
190 case GL_ONE_MINUS_CONSTANT_ALPHA
:
191 if (ctx
->Color
.BlendEnabled
)
194 b
|= RADEON_SRC_BLEND_GL_ONE
;
200 switch ( ctx
->Color
.BlendDstRGB
) {
202 b
|= RADEON_DST_BLEND_GL_ZERO
;
205 b
|= RADEON_DST_BLEND_GL_ONE
;
208 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
210 case GL_ONE_MINUS_SRC_COLOR
:
211 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
214 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
216 case GL_ONE_MINUS_SRC_ALPHA
:
217 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
220 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
222 case GL_ONE_MINUS_DST_COLOR
:
223 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
226 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
228 case GL_ONE_MINUS_DST_ALPHA
:
229 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
231 case GL_CONSTANT_COLOR
:
232 case GL_ONE_MINUS_CONSTANT_COLOR
:
233 case GL_CONSTANT_ALPHA
:
234 case GL_ONE_MINUS_CONSTANT_ALPHA
:
235 if (ctx
->Color
.BlendEnabled
)
238 b
|= RADEON_DST_BLEND_GL_ZERO
;
244 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
246 RADEON_STATECHANGE( rmesa
, ctx
);
247 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
252 /* =============================================================
256 static void radeonDepthFunc( GLcontext
*ctx
, GLenum func
)
258 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
260 RADEON_STATECHANGE( rmesa
, ctx
);
261 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
263 switch ( ctx
->Depth
.Func
) {
265 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
268 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
271 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
274 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
277 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
280 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
283 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
286 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
292 static void radeonDepthMask( GLcontext
*ctx
, GLboolean flag
)
294 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
295 RADEON_STATECHANGE( rmesa
, ctx
);
297 if ( ctx
->Depth
.Mask
) {
298 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
304 static void radeonClearDepth( GLcontext
*ctx
, GLclampd d
)
306 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
307 GLuint format
= (rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &
308 RADEON_DEPTH_FORMAT_MASK
);
311 case RADEON_DEPTH_FORMAT_16BIT_INT_Z
:
312 rmesa
->state
.depth
.clear
= d
* 0x0000ffff;
314 case RADEON_DEPTH_FORMAT_24BIT_INT_Z
:
315 rmesa
->state
.depth
.clear
= d
* 0x00ffffff;
321 /* =============================================================
326 static void radeonFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
328 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
329 union { int i
; float f
; } c
, d
;
332 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
333 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
337 if (!ctx
->Fog
.Enabled
)
339 RADEON_STATECHANGE(rmesa
, tcl
);
340 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
341 switch (ctx
->Fog
.Mode
) {
343 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
344 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
349 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
350 d
.f
= 1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
354 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
356 d
.f
= ctx
->Fog
.Density
;
359 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
361 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
368 switch (ctx
->Fog
.Mode
) {
371 d
.f
= ctx
->Fog
.Density
;
375 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
383 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
384 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
388 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
389 d
.f
= 1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
394 RADEON_STATECHANGE( rmesa
, ctx
);
395 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
396 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] =
397 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
399 case GL_FOG_COORDINATE_SOURCE_EXT
:
407 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
408 RADEON_STATECHANGE( rmesa
, fog
);
409 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
410 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
415 /* =============================================================
420 static GLboolean
intersect_rect( drm_clip_rect_t
*out
,
425 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
426 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
427 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
428 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
429 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
430 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
435 void radeonRecalcScissorRects( radeonContextPtr rmesa
)
437 drm_clip_rect_t
*out
;
440 /* Grow cliprect store?
442 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
443 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
444 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
445 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
448 if (rmesa
->state
.scissor
.pClipRects
)
449 FREE(rmesa
->state
.scissor
.pClipRects
);
451 rmesa
->state
.scissor
.pClipRects
=
452 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
453 sizeof(drm_clip_rect_t
) );
455 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
456 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
461 out
= rmesa
->state
.scissor
.pClipRects
;
462 rmesa
->state
.scissor
.numClipRects
= 0;
464 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
465 if ( intersect_rect( out
,
466 &rmesa
->pClipRects
[i
],
467 &rmesa
->state
.scissor
.rect
) ) {
468 rmesa
->state
.scissor
.numClipRects
++;
475 static void radeonUpdateScissor( GLcontext
*ctx
)
477 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
479 if ( rmesa
->dri
.drawable
) {
480 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
482 int x
= ctx
->Scissor
.X
;
483 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
484 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
485 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
487 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
488 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
489 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
490 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
492 radeonRecalcScissorRects( rmesa
);
497 static void radeonScissor( GLcontext
*ctx
,
498 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
500 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
502 if ( ctx
->Scissor
.Enabled
) {
503 RADEON_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
504 radeonUpdateScissor( ctx
);
510 /* =============================================================
514 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
516 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
517 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
518 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
520 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
521 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
523 if ( ctx
->Polygon
.CullFlag
) {
524 switch ( ctx
->Polygon
.CullFaceMode
) {
526 s
&= ~RADEON_FFACE_SOLID
;
527 t
|= RADEON_CULL_FRONT
;
530 s
&= ~RADEON_BFACE_SOLID
;
531 t
|= RADEON_CULL_BACK
;
533 case GL_FRONT_AND_BACK
:
534 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
535 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
540 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
541 RADEON_STATECHANGE(rmesa
, set
);
542 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
545 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
546 RADEON_STATECHANGE(rmesa
, tcl
);
547 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
551 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
553 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
555 RADEON_STATECHANGE( rmesa
, set
);
556 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
558 RADEON_STATECHANGE( rmesa
, tcl
);
559 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
563 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
566 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
567 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
573 /* =============================================================
576 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
578 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
580 RADEON_STATECHANGE( rmesa
, lin
);
581 RADEON_STATECHANGE( rmesa
, set
);
583 /* Line width is stored in U6.4 format.
585 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
586 if ( widthf
> 1.0 ) {
587 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
589 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
593 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
595 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
597 RADEON_STATECHANGE( rmesa
, lin
);
598 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
599 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
603 /* =============================================================
606 static void radeonColorMask( GLcontext
*ctx
,
607 GLboolean r
, GLboolean g
,
608 GLboolean b
, GLboolean a
)
610 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
611 GLuint mask
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
612 ctx
->Color
.ColorMask
[RCOMP
],
613 ctx
->Color
.ColorMask
[GCOMP
],
614 ctx
->Color
.ColorMask
[BCOMP
],
615 ctx
->Color
.ColorMask
[ACOMP
] );
617 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
618 RADEON_STATECHANGE( rmesa
, msk
);
619 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
624 /* =============================================================
628 static void radeonPolygonOffset( GLcontext
*ctx
,
629 GLfloat factor
, GLfloat units
)
631 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
632 GLfloat constant
= units
* rmesa
->state
.depth
.scale
;
634 RADEON_STATECHANGE( rmesa
, zbs
);
635 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = *(GLuint
*)&factor
;
636 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = *(GLuint
*)&constant
;
639 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
641 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
643 drm_radeon_stipple_t stipple
;
645 /* Must flip pattern upside down.
647 for ( i
= 0 ; i
< 32 ; i
++ ) {
648 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
651 /* TODO: push this into cmd mechanism
653 RADEON_FIREVERTICES( rmesa
);
654 LOCK_HARDWARE( rmesa
);
656 /* FIXME: Use window x,y offsets into stipple RAM.
658 stipple
.mask
= rmesa
->state
.stipple
.mask
;
659 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
660 &stipple
, sizeof(drm_radeon_stipple_t
) );
661 UNLOCK_HARDWARE( rmesa
);
664 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
666 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
667 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
669 /* Can't generally do unfilled via tcl, but some good special
672 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
673 if (rmesa
->TclFallback
) {
674 radeonChooseRenderState( ctx
);
675 radeonChooseVertexState( ctx
);
680 /* =============================================================
681 * Rendering attributes
683 * We really don't want to recalculate all this every time we bind a
684 * texture. These things shouldn't change all that often, so it makes
685 * sense to break them out of the core texture state update routines.
688 /* Examine lighting and texture state to determine if separate specular
691 static void radeonUpdateSpecular( GLcontext
*ctx
)
693 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
694 u_int32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
696 RADEON_STATECHANGE( rmesa
, tcl
);
698 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
699 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
700 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
701 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
702 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
704 p
&= ~RADEON_SPECULAR_ENABLE
;
706 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
709 if (ctx
->Light
.Enabled
&&
710 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
711 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
712 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
713 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
714 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
715 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
716 p
|= RADEON_SPECULAR_ENABLE
;
717 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
718 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
720 else if (ctx
->Light
.Enabled
) {
721 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
722 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
723 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
724 } else if (ctx
->Fog
.ColorSumEnabled
) {
725 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
726 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
727 p
|= RADEON_SPECULAR_ENABLE
;
729 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
732 if (ctx
->Fog
.Enabled
) {
733 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
734 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
736 /* Bizzare: have to leave lighting enabled to get fog.
738 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
741 if (NEED_SECONDARY_COLOR(ctx
)) {
742 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
744 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
747 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
748 RADEON_STATECHANGE( rmesa
, ctx
);
749 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
752 /* Update vertex/render formats
754 if (rmesa
->TclFallback
) {
755 radeonChooseRenderState( ctx
);
756 radeonChooseVertexState( ctx
);
761 /* =============================================================
766 /* Update on colormaterial, material emmissive/ambient,
767 * lightmodel.globalambient
769 static void update_global_ambient( GLcontext
*ctx
)
771 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
772 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
774 /* Need to do more if both emmissive & ambient are PREMULT:
775 * Hope this is not needed for MULT
777 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
778 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
779 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
781 COPY_3V( &fcmd
[GLT_RED
],
782 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
783 ACC_SCALE_3V( &fcmd
[GLT_RED
],
784 ctx
->Light
.Model
.Ambient
,
785 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
789 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
792 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
795 /* Update on change to
799 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
801 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
803 /* fprintf(stderr, "%s\n", __FUNCTION__); */
806 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
807 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
809 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
810 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
811 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
813 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
817 /* Also fallback for asym colormaterial mode in twoside lighting...
819 static void check_twoside_fallback( GLcontext
*ctx
)
821 GLboolean fallback
= GL_FALSE
;
824 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
825 if (ctx
->Light
.ColorMaterialEnabled
&&
826 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
827 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
830 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
831 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
832 ctx
->Light
.Material
.Attrib
[i
+1],
833 sizeof(GLfloat
)*4) != 0) {
840 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
844 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
846 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
847 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
849 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
850 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
851 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
852 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
854 if (ctx
->Light
.ColorMaterialEnabled
) {
855 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
857 if (mask
& MAT_BIT_FRONT_EMISSION
) {
858 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
859 RADEON_EMISSIVE_SOURCE_SHIFT
);
862 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
863 RADEON_EMISSIVE_SOURCE_SHIFT
);
866 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
867 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
868 RADEON_AMBIENT_SOURCE_SHIFT
);
871 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
872 RADEON_AMBIENT_SOURCE_SHIFT
);
875 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
876 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
877 RADEON_DIFFUSE_SOURCE_SHIFT
);
880 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
881 RADEON_DIFFUSE_SOURCE_SHIFT
);
884 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
885 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
886 RADEON_SPECULAR_SOURCE_SHIFT
);
889 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
890 RADEON_SPECULAR_SOURCE_SHIFT
);
896 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
897 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
898 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
899 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
902 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
903 RADEON_STATECHANGE( rmesa
, tcl
);
904 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
908 void radeonUpdateMaterial( GLcontext
*ctx
)
910 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
911 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
912 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
915 if (ctx
->Light
.ColorMaterialEnabled
)
916 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
918 if (RADEON_DEBUG
& DEBUG_STATE
)
919 fprintf(stderr
, "%s\n", __FUNCTION__
);
922 if (mask
& MAT_BIT_FRONT_EMISSION
) {
923 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
924 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
925 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
926 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
928 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
929 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
930 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
931 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
932 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
934 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
935 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
936 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
937 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
938 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
940 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
941 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
942 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
943 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
944 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
946 if (mask
& MAT_BIT_FRONT_SHININESS
) {
947 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
950 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
952 check_twoside_fallback( ctx
);
953 /* update_global_ambient( ctx );*/
958 * _MESA_NEW_NEED_EYE_COORDS
960 * Uses derived state from mesa:
969 * which are calculated in light.c and are correct for the current
970 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
971 * and _MESA_NEW_NEED_EYE_COORDS.
973 static void update_light( GLcontext
*ctx
)
975 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
977 /* Have to check these, or have an automatic shortcircuit mechanism
978 * to remove noop statechanges. (Or just do a better job on the
982 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
984 if (ctx
->_NeedEyeCoords
)
985 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
987 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
990 /* Leave this test disabled: (unexplained q3 lockup) (even with
993 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
995 RADEON_STATECHANGE( rmesa
, tcl
);
996 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
1001 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
1002 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1003 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1004 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1005 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1006 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1011 if (ctx
->Light
.Enabled
) {
1013 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1014 if (ctx
->Light
.Light
[p
].Enabled
) {
1015 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1016 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
1018 if (l
->EyePosition
[3] == 0.0) {
1019 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1020 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1021 fcmd
[LIT_POSITION_W
] = 0;
1022 fcmd
[LIT_DIRECTION_W
] = 0;
1024 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1025 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1026 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1027 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1028 fcmd
[LIT_DIRECTION_W
] = 0;
1031 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1037 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
1038 GLenum pname
, const GLfloat
*params
)
1040 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1041 GLint p
= light
- GL_LIGHT0
;
1042 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1043 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1050 update_light_colors( ctx
, p
);
1053 case GL_SPOT_DIRECTION
:
1054 /* picked up in update_light */
1058 /* positions picked up in update_light, but can do flag here */
1060 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1062 /* FIXME: Set RANGE_ATTEN only when needed */
1064 flag
= RADEON_LIGHT_1_IS_LOCAL
;
1066 flag
= RADEON_LIGHT_0_IS_LOCAL
;
1068 RADEON_STATECHANGE(rmesa
, tcl
);
1069 if (l
->EyePosition
[3] != 0.0F
)
1070 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1072 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1076 case GL_SPOT_EXPONENT
:
1077 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1078 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1081 case GL_SPOT_CUTOFF
: {
1082 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
1083 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1085 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1086 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1088 RADEON_STATECHANGE(rmesa
, tcl
);
1089 if (l
->SpotCutoff
!= 180.0F
)
1090 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1092 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1097 case GL_CONSTANT_ATTENUATION
:
1098 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1099 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1100 if ( params
[0] == 0.0 )
1101 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1103 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1105 case GL_LINEAR_ATTENUATION
:
1106 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1107 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1109 case GL_QUADRATIC_ATTENUATION
:
1110 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1111 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1117 /* Set RANGE_ATTEN only when needed */
1120 case GL_CONSTANT_ATTENUATION
:
1121 case GL_LINEAR_ATTENUATION
:
1122 case GL_QUADRATIC_ATTENUATION
:
1124 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1125 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1126 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1127 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1128 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1129 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1131 if ( l
->EyePosition
[3] == 0.0F
||
1132 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1133 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1134 /* Disable attenuation */
1135 icmd
[idx
] &= ~atten_flag
;
1137 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1138 /* Enable only constant portion of attenuation calculation */
1139 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1141 /* Enable full attenuation calculation */
1142 icmd
[idx
] &= ~atten_const_flag
;
1143 icmd
[idx
] |= atten_flag
;
1147 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1158 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1159 const GLfloat
*param
)
1161 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1164 case GL_LIGHT_MODEL_AMBIENT
:
1165 update_global_ambient( ctx
);
1168 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1169 RADEON_STATECHANGE( rmesa
, tcl
);
1170 if (ctx
->Light
.Model
.LocalViewer
)
1171 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1173 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1176 case GL_LIGHT_MODEL_TWO_SIDE
:
1177 RADEON_STATECHANGE( rmesa
, tcl
);
1178 if (ctx
->Light
.Model
.TwoSide
)
1179 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1181 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1183 check_twoside_fallback( ctx
);
1185 if (rmesa
->TclFallback
) {
1186 radeonChooseRenderState( ctx
);
1187 radeonChooseVertexState( ctx
);
1191 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1192 radeonUpdateSpecular(ctx
);
1200 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1202 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1203 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1205 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1206 RADEON_ALPHA_SHADE_MASK
|
1207 RADEON_SPECULAR_SHADE_MASK
|
1208 RADEON_FOG_SHADE_MASK
);
1212 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1213 RADEON_ALPHA_SHADE_FLAT
|
1214 RADEON_SPECULAR_SHADE_FLAT
|
1215 RADEON_FOG_SHADE_FLAT
);
1218 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1219 RADEON_ALPHA_SHADE_GOURAUD
|
1220 RADEON_SPECULAR_SHADE_GOURAUD
|
1221 RADEON_FOG_SHADE_GOURAUD
);
1227 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1228 RADEON_STATECHANGE( rmesa
, set
);
1229 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1234 /* =============================================================
1238 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1240 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1241 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1242 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1244 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1245 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1246 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1247 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1248 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1251 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1253 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1256 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1257 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1258 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1260 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1261 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1262 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1263 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1264 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1270 /* =============================================================
1275 radeonStencilFuncSeparate( GLcontext
*ctx
, GLenum face
, GLenum func
,
1276 GLint ref
, GLuint mask
)
1278 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1279 GLuint refmask
= ((ctx
->Stencil
.Ref
[0] << RADEON_STENCIL_REF_SHIFT
) |
1280 (ctx
->Stencil
.ValueMask
[0] << RADEON_STENCIL_MASK_SHIFT
));
1282 RADEON_STATECHANGE( rmesa
, ctx
);
1283 RADEON_STATECHANGE( rmesa
, msk
);
1285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1286 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1287 RADEON_STENCIL_VALUE_MASK
);
1289 switch ( ctx
->Stencil
.Function
[0] ) {
1291 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1294 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1297 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1303 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1306 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1309 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1312 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1316 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1320 radeonStencilMaskSeparate( GLcontext
*ctx
, GLenum face
, GLuint mask
)
1322 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1324 RADEON_STATECHANGE( rmesa
, msk
);
1325 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1326 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1327 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
);
1330 static void radeonStencilOpSeparate( GLcontext
*ctx
, GLenum face
, GLenum fail
,
1331 GLenum zfail
, GLenum zpass
)
1333 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1335 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1336 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1337 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1339 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1340 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1341 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1342 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1343 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1344 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1346 if (rmesa
->radeonScreen
->chipset
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1347 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1348 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1349 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1350 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1351 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1352 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1355 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1356 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1357 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1358 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1359 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1360 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1363 RADEON_STATECHANGE( rmesa
, ctx
);
1364 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1365 RADEON_STENCIL_ZFAIL_MASK
|
1366 RADEON_STENCIL_ZPASS_MASK
);
1368 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1370 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1373 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1376 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1379 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1382 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1385 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1388 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1391 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1395 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1397 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1400 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1403 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1406 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1409 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1412 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1415 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1418 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1422 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1424 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1427 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1430 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1433 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1436 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1439 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1442 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1445 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1450 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1452 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1454 rmesa
->state
.stencil
.clear
=
1455 ((GLuint
) ctx
->Stencil
.Clear
|
1456 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1457 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
));
1461 /* =============================================================
1462 * Window position and viewport transformation
1466 * To correctly position primitives:
1468 #define SUBPIXEL_X 0.125
1469 #define SUBPIXEL_Y 0.125
1473 * Called when window size or position changes or viewport or depth range
1474 * state is changed. We update the hardware viewport state here.
1476 void radeonUpdateWindow( GLcontext
*ctx
)
1478 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1479 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1480 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1481 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1482 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1484 GLfloat sx
= v
[MAT_SX
];
1485 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1486 GLfloat sy
= - v
[MAT_SY
];
1487 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1488 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1489 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1490 RADEON_FIREVERTICES( rmesa
);
1491 RADEON_STATECHANGE( rmesa
, vpt
);
1493 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = *(GLuint
*)&sx
;
1494 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1495 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = *(GLuint
*)&sy
;
1496 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1497 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = *(GLuint
*)&sz
;
1498 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = *(GLuint
*)&tz
;
1502 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1503 GLsizei width
, GLsizei height
)
1505 /* Don't pipeline viewport changes, conflict with window offset
1506 * setting below. Could apply deltas to rescue pipelined viewport
1507 * values, or keep the originals hanging around.
1509 RADEON_FIREVERTICES( RADEON_CONTEXT(ctx
) );
1510 radeonUpdateWindow( ctx
);
1513 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1516 radeonUpdateWindow( ctx
);
1519 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1521 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1522 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1523 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1524 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1525 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1527 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1528 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1530 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != *(GLuint
*)&tx
||
1531 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != *(GLuint
*)&ty
)
1533 /* Note: this should also modify whatever data the context reset
1536 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1537 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1539 /* update polygon stipple x/y screen offset */
1542 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1544 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1545 RADEON_STIPPLE_Y_OFFSET_MASK
);
1547 /* add magic offsets, then invert */
1548 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1549 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1550 & RADEON_STIPPLE_COORD_MASK
);
1552 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1553 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1555 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1556 RADEON_STATECHANGE( rmesa
, msc
);
1557 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1562 radeonUpdateScissor( ctx
);
1567 /* =============================================================
1571 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1573 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1575 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1576 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1577 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1578 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1579 rmesa
->state
.color
.clear
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
1580 c
[0], c
[1], c
[2], c
[3] );
1584 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1586 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1587 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1591 static GLuint radeon_rop_tab
[] = {
1594 RADEON_ROP_AND_REVERSE
,
1596 RADEON_ROP_AND_INVERTED
,
1603 RADEON_ROP_OR_REVERSE
,
1604 RADEON_ROP_COPY_INVERTED
,
1605 RADEON_ROP_OR_INVERTED
,
1610 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1612 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1613 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1617 RADEON_STATECHANGE( rmesa
, msk
);
1618 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1623 * Set up the cliprects for either front or back-buffer drawing.
1625 void radeonSetCliprects( radeonContextPtr rmesa
)
1627 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1629 if (rmesa
->glCtx
->DrawBuffer
->_ColorDrawBufferMask
[0]
1630 == BUFFER_BIT_BACK_LEFT
) {
1631 /* Can't ignore 2d windows if we are page flipping.
1633 if ( dPriv
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1634 rmesa
->numClipRects
= dPriv
->numClipRects
;
1635 rmesa
->pClipRects
= dPriv
->pClipRects
;
1638 rmesa
->numClipRects
= dPriv
->numBackClipRects
;
1639 rmesa
->pClipRects
= dPriv
->pBackClipRects
;
1643 /* front buffer (or none, or multiple buffers */
1644 rmesa
->numClipRects
= dPriv
->numClipRects
;
1645 rmesa
->pClipRects
= dPriv
->pClipRects
;
1648 if (rmesa
->state
.scissor
.enabled
)
1649 radeonRecalcScissorRects( rmesa
);
1654 * Called via glDrawBuffer.
1656 static void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
1658 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1660 if (RADEON_DEBUG
& DEBUG_DRI
)
1661 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1662 _mesa_lookup_enum_by_nr( mode
));
1664 RADEON_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1667 * _ColorDrawBufferMask is easier to cope with than <mode>.
1668 * Check for software fallback, update cliprects.
1670 switch ( ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] ) {
1671 case BUFFER_BIT_FRONT_LEFT
:
1672 case BUFFER_BIT_BACK_LEFT
:
1673 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1676 /* 0 (GL_NONE) buffers or multiple color drawing buffers */
1677 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1681 radeonSetCliprects( rmesa
);
1683 /* We'll set the drawing engine's offset/pitch parameters later
1684 * when we update other state.
1688 static void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
1690 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1694 /* =============================================================
1695 * State enable/disable
1698 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1700 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1703 if ( RADEON_DEBUG
& DEBUG_STATE
)
1704 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1705 _mesa_lookup_enum_by_nr( cap
),
1706 state
? "GL_TRUE" : "GL_FALSE" );
1709 /* Fast track this one...
1717 RADEON_STATECHANGE( rmesa
, ctx
);
1719 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1721 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1726 RADEON_STATECHANGE( rmesa
, ctx
);
1728 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1730 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1732 if ( ctx
->Color
._LogicOpEnabled
) {
1733 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1735 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1738 /* Catch a possible fallback:
1741 ctx
->Driver
.BlendEquationSeparate( ctx
,
1742 ctx
->Color
.BlendEquationRGB
,
1743 ctx
->Color
.BlendEquationA
);
1744 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1745 ctx
->Color
.BlendDstRGB
,
1746 ctx
->Color
.BlendSrcA
,
1747 ctx
->Color
.BlendDstA
);
1750 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1751 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1755 case GL_CLIP_PLANE0
:
1756 case GL_CLIP_PLANE1
:
1757 case GL_CLIP_PLANE2
:
1758 case GL_CLIP_PLANE3
:
1759 case GL_CLIP_PLANE4
:
1760 case GL_CLIP_PLANE5
:
1761 p
= cap
-GL_CLIP_PLANE0
;
1762 RADEON_STATECHANGE( rmesa
, tcl
);
1764 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1765 radeonClipPlane( ctx
, cap
, NULL
);
1768 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1772 case GL_COLOR_MATERIAL
:
1773 radeonColorMaterial( ctx
, 0, 0 );
1774 radeonUpdateMaterial( ctx
);
1778 radeonCullFace( ctx
, 0 );
1782 RADEON_STATECHANGE(rmesa
, ctx
);
1784 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1786 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1791 RADEON_STATECHANGE(rmesa
, ctx
);
1793 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1794 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1796 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1797 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1802 RADEON_STATECHANGE(rmesa
, ctx
);
1804 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1805 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1807 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1808 RADEON_STATECHANGE(rmesa
, tcl
);
1809 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1811 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1812 if (rmesa
->TclFallback
)
1813 radeonChooseVertexState( ctx
);
1814 _mesa_allow_light_in_model( ctx
, !state
);
1825 RADEON_STATECHANGE(rmesa
, tcl
);
1826 p
= cap
- GL_LIGHT0
;
1828 flag
= (RADEON_LIGHT_1_ENABLE
|
1829 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1830 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1832 flag
= (RADEON_LIGHT_0_ENABLE
|
1833 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1834 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1837 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1839 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1843 update_light_colors( ctx
, p
);
1847 RADEON_STATECHANGE(rmesa
, tcl
);
1848 radeonUpdateSpecular(ctx
);
1849 check_twoside_fallback( ctx
);
1852 case GL_LINE_SMOOTH
:
1853 RADEON_STATECHANGE( rmesa
, ctx
);
1855 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1857 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1861 case GL_LINE_STIPPLE
:
1862 RADEON_STATECHANGE( rmesa
, ctx
);
1864 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1866 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1870 case GL_COLOR_LOGIC_OP
:
1871 RADEON_STATECHANGE( rmesa
, ctx
);
1872 if ( ctx
->Color
._LogicOpEnabled
) {
1873 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1875 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1880 RADEON_STATECHANGE( rmesa
, tcl
);
1882 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1884 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1888 case GL_POLYGON_OFFSET_POINT
:
1889 RADEON_STATECHANGE( rmesa
, set
);
1891 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1893 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1897 case GL_POLYGON_OFFSET_LINE
:
1898 RADEON_STATECHANGE( rmesa
, set
);
1900 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1902 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1906 case GL_POLYGON_OFFSET_FILL
:
1907 RADEON_STATECHANGE( rmesa
, set
);
1909 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1911 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1915 case GL_POLYGON_SMOOTH
:
1916 RADEON_STATECHANGE( rmesa
, ctx
);
1918 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1920 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1924 case GL_POLYGON_STIPPLE
:
1925 RADEON_STATECHANGE(rmesa
, ctx
);
1927 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1929 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1933 case GL_RESCALE_NORMAL_EXT
: {
1934 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1935 RADEON_STATECHANGE( rmesa
, tcl
);
1937 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1939 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1944 case GL_SCISSOR_TEST
:
1945 RADEON_FIREVERTICES( rmesa
);
1946 rmesa
->state
.scissor
.enabled
= state
;
1947 radeonUpdateScissor( ctx
);
1950 case GL_STENCIL_TEST
:
1951 if ( rmesa
->state
.stencil
.hwBuffer
) {
1952 RADEON_STATECHANGE( rmesa
, ctx
);
1954 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1956 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1959 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1963 case GL_TEXTURE_GEN_Q
:
1964 case GL_TEXTURE_GEN_R
:
1965 case GL_TEXTURE_GEN_S
:
1966 case GL_TEXTURE_GEN_T
:
1967 /* Picked up in radeonUpdateTextureState.
1969 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1972 case GL_COLOR_SUM_EXT
:
1973 radeonUpdateSpecular ( ctx
);
1982 static void radeonLightingSpaceChange( GLcontext
*ctx
)
1984 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1986 RADEON_STATECHANGE( rmesa
, tcl
);
1988 if (RADEON_DEBUG
& DEBUG_STATE
)
1989 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1990 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1992 if (ctx
->_NeedEyeCoords
)
1993 tmp
= ctx
->Transform
.RescaleNormals
;
1995 tmp
= !ctx
->Transform
.RescaleNormals
;
1998 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
2000 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
2003 if (RADEON_DEBUG
& DEBUG_STATE
)
2004 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2005 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
2008 /* =============================================================
2009 * Deferred state management - matrices, textures, other?
2012 static void texmat_set_texrect( radeonContextPtr rmesa
,
2013 struct gl_texture_object
*tObj
, GLuint unit
)
2015 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
2016 _math_matrix_set_identity( &rmesa
->tmpmat
[unit
] );
2017 rmesa
->tmpmat
[unit
].m
[0] = 1.0 / baseImage
->Width
;
2018 rmesa
->tmpmat
[unit
].m
[5] = 1.0 / baseImage
->Height
;
2022 static void texmat_fixup_texrect( radeonContextPtr rmesa
,
2023 struct gl_texture_object
*tObj
, GLuint unit
)
2025 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
2027 for (i
= 0; i
< 4; i
++) {
2028 rmesa
->tmpmat
[unit
].m
[i
] = rmesa
->tmpmat
[unit
].m
[i
] / baseImage
->Width
;
2029 rmesa
->tmpmat
[unit
].m
[i
+4] = rmesa
->tmpmat
[unit
].m
[i
+4] / baseImage
->Height
;
2033 void radeonUploadTexMatrix( radeonContextPtr rmesa
,
2034 int unit
, GLboolean swapcols
)
2036 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
2037 vector looks like this probably: (s t r|q 0) (not sure if the last coord
2038 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
2039 texgen generates all 4 coords, at least tests with projtex indicated that.
2040 So: if we need the q coord in the end (solely determined by the texture
2041 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
2042 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
2043 column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
2044 will get submitted in the "wrong", i.e. 3rd, slot.
2045 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
2046 size and using the texture matrix to swap the r and q coords around (ut2k3
2047 does exactly that), so we don't need the 3rd / 4th column swap - still need
2048 the 3rd / 4th row swap of course. This will potentially break for apps which
2049 use TexCoord3x just for fun. Additionally, it will never work if an app uses
2050 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
2051 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
2052 incredibly hard to detect so we can't just fallback in such a case. Assume
2053 it never happens... - rs
2056 int idx
= TEXMAT_0
+ unit
;
2057 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
2059 struct gl_texture_unit tUnit
= rmesa
->glCtx
->Texture
.Unit
[unit
];
2060 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
2062 rmesa
->TexMatColSwap
&= ~(1 << unit
);
2063 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
2065 rmesa
->TexMatColSwap
|= 1 << unit
;
2066 /* attention some elems are swapped 2 times! */
2079 /* those last 4 are probably never used */
2086 for (i
= 0; i
< 2; i
++) {
2090 *dest
++ = src
[i
+12];
2092 for (i
= 3; i
>= 2; i
--) {
2096 *dest
++ = src
[i
+12];
2101 /* never used currently - no swapping needed at all presumably */
2102 for (i
= 0 ; i
< 4 ; i
++) {
2106 *dest
++ = src
[i
+12];
2110 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2114 static void upload_matrix( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2116 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2120 for (i
= 0 ; i
< 4 ; i
++) {
2124 *dest
++ = src
[i
+12];
2127 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2130 static void upload_matrix_t( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2132 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2133 memcpy(dest
, src
, 16*sizeof(float));
2134 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2138 static void update_texturematrix( GLcontext
*ctx
)
2140 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
2141 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
2142 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2144 GLuint texMatEnabled
= 0;
2145 rmesa
->NeedTexMatrix
= 0;
2146 rmesa
->TexMatColSwap
= 0;
2148 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
2149 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2150 GLboolean needMatrix
= GL_FALSE
;
2151 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2152 needMatrix
= GL_TRUE
;
2153 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2154 RADEON_TEXMAT_0_ENABLE
) << unit
;
2156 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2157 /* Need to preconcatenate any active texgen
2158 * obj/eyeplane matrices:
2160 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
2161 ctx
->TextureMatrixStack
[unit
].Top
,
2162 &rmesa
->TexGenMatrix
[unit
] );
2165 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
2166 ctx
->TextureMatrixStack
[unit
].Top
);
2169 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2170 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
2171 needMatrix
= GL_TRUE
;
2173 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
== TEXTURE_RECT_BIT
) {
2174 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2175 RADEON_TEXMAT_0_ENABLE
) << unit
;
2177 texmat_fixup_texrect( rmesa
, ctx
->Texture
.Unit
[unit
]._Current
, unit
);
2179 texmat_set_texrect( rmesa
, ctx
->Texture
.Unit
[unit
]._Current
, unit
);
2180 needMatrix
= GL_TRUE
;
2183 rmesa
->NeedTexMatrix
|= 1 << unit
;
2184 radeonUploadTexMatrix( rmesa
, unit
,
2185 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
2190 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
2192 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2193 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2194 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
2195 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
2197 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
2198 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
2199 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
2200 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
2201 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
2202 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
2204 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2205 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2207 RADEON_STATECHANGE(rmesa
, tcl
);
2208 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2209 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2215 * Tell the card where to render (offset, pitch).
2216 * Effected by glDrawBuffer, etc
2219 radeonUpdateDrawBuffer(GLcontext
*ctx
)
2221 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2222 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
2223 driRenderbuffer
*drb
;
2225 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
2227 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
2229 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
2231 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
2234 /* drawing to multiple buffers, or none */
2239 assert(drb
->flippedPitch
);
2241 RADEON_STATECHANGE( rmesa
, ctx
);
2243 /* Note: we used the (possibly) page-flipped values */
2244 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
2245 = ((drb
->flippedOffset
+ rmesa
->radeonScreen
->fbLocation
)
2246 & RADEON_COLOROFFSET_MASK
);
2247 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
2248 if (rmesa
->sarea
->tiling_enabled
) {
2249 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= RADEON_COLOR_TILE_ENABLE
;
2254 void radeonValidateState( GLcontext
*ctx
)
2256 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2257 GLuint new_state
= rmesa
->NewGLState
;
2259 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2260 radeonUpdateDrawBuffer(ctx
);
2263 if (new_state
& _NEW_TEXTURE
) {
2264 radeonUpdateTextureState( ctx
);
2265 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2268 /* Need an event driven matrix update?
2270 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2271 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2273 /* Need these for lighting (shouldn't upload otherwise)
2275 if (new_state
& (_NEW_MODELVIEW
)) {
2276 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2277 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2280 /* Does this need to be triggered on eg. modelview for
2281 * texgen-derived objplane/eyeplane matrices?
2283 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2284 update_texturematrix( ctx
);
2287 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2288 update_light( ctx
);
2291 /* emit all active clip planes if projection matrix changes.
2293 if (new_state
& (_NEW_PROJECTION
)) {
2294 if (ctx
->Transform
.ClipPlanesEnabled
)
2295 radeonUpdateClipPlanes( ctx
);
2299 rmesa
->NewGLState
= 0;
2303 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2305 _swrast_InvalidateState( ctx
, new_state
);
2306 _swsetup_InvalidateState( ctx
, new_state
);
2307 _ac_InvalidateState( ctx
, new_state
);
2308 _tnl_InvalidateState( ctx
, new_state
);
2309 _ae_invalidate_state( ctx
, new_state
);
2310 RADEON_CONTEXT(ctx
)->NewGLState
|= new_state
;
2311 radeonVtxfmtInvalidate( ctx
);
2315 /* A hack. Need a faster way to find this out.
2317 static GLboolean
check_material( GLcontext
*ctx
)
2319 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2322 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2323 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2325 if (tnl
->vb
.AttribPtr
[i
] &&
2326 tnl
->vb
.AttribPtr
[i
]->stride
)
2333 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2335 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2336 GLboolean has_material
;
2339 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2343 if (rmesa
->NewGLState
)
2344 radeonValidateState( ctx
);
2346 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2349 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2352 /* Run the pipeline.
2354 _tnl_run_pipeline( ctx
);
2357 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2362 /* Initialize the driver's state functions.
2363 * Many of the ctx->Driver functions might have been initialized to
2364 * software defaults in the earlier _mesa_init_driver_functions() call.
2366 void radeonInitStateFuncs( GLcontext
*ctx
)
2368 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2369 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2371 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2372 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2374 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2375 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2376 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2377 ctx
->Driver
.ClearColor
= radeonClearColor
;
2378 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2379 ctx
->Driver
.ClearIndex
= NULL
;
2380 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2381 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2382 ctx
->Driver
.ColorMask
= radeonColorMask
;
2383 ctx
->Driver
.CullFace
= radeonCullFace
;
2384 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2385 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2386 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2387 ctx
->Driver
.Enable
= radeonEnable
;
2388 ctx
->Driver
.Fogfv
= radeonFogfv
;
2389 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2390 ctx
->Driver
.Hint
= NULL
;
2391 ctx
->Driver
.IndexMask
= NULL
;
2392 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2393 ctx
->Driver
.Lightfv
= radeonLightfv
;
2394 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2395 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2396 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2397 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2398 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2399 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2400 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2401 ctx
->Driver
.Scissor
= radeonScissor
;
2402 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2403 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2404 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2405 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2406 ctx
->Driver
.Viewport
= radeonViewport
;
2408 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2409 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;