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"
43 #include "swrast/swrast.h"
44 #include "array_cache/acache.h"
46 #include "tnl/t_pipeline.h"
47 #include "main/light.h"
48 #include "swrast_setup/swrast_setup.h"
50 #include "radeon_context.h"
51 #include "radeon_ioctl.h"
52 #include "radeon_state.h"
53 #include "radeon_tcl.h"
54 #include "radeon_tex.h"
55 #include "radeon_swtcl.h"
56 #include "radeon_vtxfmt.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 radeonBlendEquation( GLcontext
*ctx
, GLenum mode
)
107 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
108 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
109 GLboolean fallback
= GL_FALSE
;
114 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
117 case GL_FUNC_SUBTRACT
:
118 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
122 if (ctx
->Color
.BlendEnabled
)
125 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
129 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
131 RADEON_STATECHANGE( rmesa
, ctx
);
132 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
133 if ( ctx
->Color
.ColorLogicOpEnabled
) {
134 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
136 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
141 static void radeonBlendFunc( GLcontext
*ctx
, GLenum sfactor
, GLenum dfactor
)
143 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
144 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
145 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
146 GLboolean fallback
= GL_FALSE
;
148 switch ( ctx
->Color
.BlendSrcRGB
) {
150 b
|= RADEON_SRC_BLEND_GL_ZERO
;
153 b
|= RADEON_SRC_BLEND_GL_ONE
;
156 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
158 case GL_ONE_MINUS_DST_COLOR
:
159 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
162 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
164 case GL_ONE_MINUS_SRC_COLOR
:
165 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
168 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
170 case GL_ONE_MINUS_SRC_ALPHA
:
171 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
174 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
176 case GL_ONE_MINUS_DST_ALPHA
:
177 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
179 case GL_SRC_ALPHA_SATURATE
:
180 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
182 case GL_CONSTANT_COLOR
:
183 case GL_ONE_MINUS_CONSTANT_COLOR
:
184 case GL_CONSTANT_ALPHA
:
185 case GL_ONE_MINUS_CONSTANT_ALPHA
:
186 if (ctx
->Color
.BlendEnabled
)
189 b
|= RADEON_SRC_BLEND_GL_ONE
;
195 switch ( ctx
->Color
.BlendDstRGB
) {
197 b
|= RADEON_DST_BLEND_GL_ZERO
;
200 b
|= RADEON_DST_BLEND_GL_ONE
;
203 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
205 case GL_ONE_MINUS_SRC_COLOR
:
206 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
209 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
211 case GL_ONE_MINUS_SRC_ALPHA
:
212 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
215 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
217 case GL_ONE_MINUS_DST_COLOR
:
218 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
221 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
223 case GL_ONE_MINUS_DST_ALPHA
:
224 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
226 case GL_CONSTANT_COLOR
:
227 case GL_ONE_MINUS_CONSTANT_COLOR
:
228 case GL_CONSTANT_ALPHA
:
229 case GL_ONE_MINUS_CONSTANT_ALPHA
:
230 if (ctx
->Color
.BlendEnabled
)
233 b
|= RADEON_DST_BLEND_GL_ZERO
;
239 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
241 RADEON_STATECHANGE( rmesa
, ctx
);
242 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
246 static void radeonBlendFuncSeparate( GLcontext
*ctx
,
247 GLenum sfactorRGB
, GLenum dfactorRGB
,
248 GLenum sfactorA
, GLenum dfactorA
)
250 radeonBlendFunc( ctx
, sfactorRGB
, dfactorRGB
);
254 /* =============================================================
258 static void radeonDepthFunc( GLcontext
*ctx
, GLenum func
)
260 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
262 RADEON_STATECHANGE( rmesa
, ctx
);
263 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
265 switch ( ctx
->Depth
.Func
) {
267 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
294 static void radeonDepthMask( GLcontext
*ctx
, GLboolean flag
)
296 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
297 RADEON_STATECHANGE( rmesa
, ctx
);
299 if ( ctx
->Depth
.Mask
) {
300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
306 static void radeonClearDepth( GLcontext
*ctx
, GLclampd d
)
308 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
309 GLuint format
= (rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &
310 RADEON_DEPTH_FORMAT_MASK
);
313 case RADEON_DEPTH_FORMAT_16BIT_INT_Z
:
314 rmesa
->state
.depth
.clear
= d
* 0x0000ffff;
316 case RADEON_DEPTH_FORMAT_24BIT_INT_Z
:
317 rmesa
->state
.depth
.clear
= d
* 0x00ffffff;
323 /* =============================================================
328 static void radeonFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
330 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
331 union { int i
; float f
; } c
, d
;
334 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
335 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
339 if (!ctx
->Fog
.Enabled
)
341 RADEON_STATECHANGE(rmesa
, tcl
);
342 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
343 switch (ctx
->Fog
.Mode
) {
345 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
346 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
351 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
352 d
.f
= 1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
356 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
358 d
.f
= ctx
->Fog
.Density
;
361 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
363 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
370 switch (ctx
->Fog
.Mode
) {
373 d
.f
= ctx
->Fog
.Density
;
377 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
385 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
386 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
390 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
391 d
.f
= 1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
396 RADEON_STATECHANGE( rmesa
, ctx
);
397 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
398 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] =
399 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
401 case GL_FOG_COORDINATE_SOURCE_EXT
:
409 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
410 RADEON_STATECHANGE( rmesa
, fog
);
411 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
412 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
417 /* =============================================================
422 static GLboolean
intersect_rect( XF86DRIClipRectPtr out
,
423 XF86DRIClipRectPtr a
,
424 XF86DRIClipRectPtr b
)
427 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
428 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
429 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
430 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
431 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
432 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
437 void radeonRecalcScissorRects( radeonContextPtr rmesa
)
439 XF86DRIClipRectPtr out
;
442 /* Grow cliprect store?
444 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
445 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
446 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
447 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
450 if (rmesa
->state
.scissor
.pClipRects
)
451 FREE(rmesa
->state
.scissor
.pClipRects
);
453 rmesa
->state
.scissor
.pClipRects
=
454 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
455 sizeof(XF86DRIClipRectRec
) );
457 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
458 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
463 out
= rmesa
->state
.scissor
.pClipRects
;
464 rmesa
->state
.scissor
.numClipRects
= 0;
466 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
467 if ( intersect_rect( out
,
468 &rmesa
->pClipRects
[i
],
469 &rmesa
->state
.scissor
.rect
) ) {
470 rmesa
->state
.scissor
.numClipRects
++;
477 static void radeonUpdateScissor( GLcontext
*ctx
)
479 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
481 if ( rmesa
->dri
.drawable
) {
482 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
484 int x
= ctx
->Scissor
.X
;
485 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
486 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
487 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
489 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
490 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
491 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
492 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
494 radeonRecalcScissorRects( rmesa
);
499 static void radeonScissor( GLcontext
*ctx
,
500 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
502 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
504 if ( ctx
->Scissor
.Enabled
) {
505 RADEON_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
506 radeonUpdateScissor( ctx
);
512 /* =============================================================
516 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
518 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
519 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
520 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
522 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
523 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
525 if ( ctx
->Polygon
.CullFlag
) {
526 switch ( ctx
->Polygon
.CullFaceMode
) {
528 s
&= ~RADEON_FFACE_SOLID
;
529 t
|= RADEON_CULL_FRONT
;
532 s
&= ~RADEON_BFACE_SOLID
;
533 t
|= RADEON_CULL_BACK
;
535 case GL_FRONT_AND_BACK
:
536 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
537 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
542 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
543 RADEON_STATECHANGE(rmesa
, set
);
544 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
547 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
548 RADEON_STATECHANGE(rmesa
, tcl
);
549 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
553 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
555 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
557 RADEON_STATECHANGE( rmesa
, set
);
558 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
560 RADEON_STATECHANGE( rmesa
, tcl
);
561 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
565 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
568 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
569 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
575 /* =============================================================
578 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
580 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
582 RADEON_STATECHANGE( rmesa
, lin
);
583 RADEON_STATECHANGE( rmesa
, set
);
585 /* Line width is stored in U6.4 format.
587 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
588 if ( widthf
> 1.0 ) {
589 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
591 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
595 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
597 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
599 RADEON_STATECHANGE( rmesa
, lin
);
600 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
601 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
605 /* =============================================================
608 static void radeonColorMask( GLcontext
*ctx
,
609 GLboolean r
, GLboolean g
,
610 GLboolean b
, GLboolean a
)
612 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
613 GLuint mask
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
614 ctx
->Color
.ColorMask
[RCOMP
],
615 ctx
->Color
.ColorMask
[GCOMP
],
616 ctx
->Color
.ColorMask
[BCOMP
],
617 ctx
->Color
.ColorMask
[ACOMP
] );
619 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
620 RADEON_STATECHANGE( rmesa
, msk
);
621 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
626 /* =============================================================
630 static void radeonPolygonOffset( GLcontext
*ctx
,
631 GLfloat factor
, GLfloat units
)
633 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
634 GLfloat constant
= units
* rmesa
->state
.depth
.scale
;
636 RADEON_STATECHANGE( rmesa
, zbs
);
637 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = *(GLuint
*)&factor
;
638 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = *(GLuint
*)&constant
;
641 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
643 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
645 drmRadeonStipple stipple
;
647 /* Must flip pattern upside down.
649 for ( i
= 0 ; i
< 32 ; i
++ ) {
650 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
653 /* TODO: push this into cmd mechanism
655 RADEON_FIREVERTICES( rmesa
);
656 LOCK_HARDWARE( rmesa
);
658 /* FIXME: Use window x,y offsets into stipple RAM.
660 stipple
.mask
= rmesa
->state
.stipple
.mask
;
661 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
662 &stipple
, sizeof(drmRadeonStipple
) );
663 UNLOCK_HARDWARE( rmesa
);
666 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
668 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
669 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
671 /* Can't generally do unfilled via tcl, but some good special
674 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
675 if (rmesa
->TclFallback
) {
676 radeonChooseRenderState( ctx
);
677 radeonChooseVertexState( ctx
);
682 /* =============================================================
683 * Rendering attributes
685 * We really don't want to recalculate all this every time we bind a
686 * texture. These things shouldn't change all that often, so it makes
687 * sense to break them out of the core texture state update routines.
690 /* Examine lighting and texture state to determine if separate specular
693 static void radeonUpdateSpecular( GLcontext
*ctx
)
695 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
696 CARD32 p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
698 RADEON_STATECHANGE( rmesa
, tcl
);
700 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
701 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
702 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
703 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
704 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
706 p
&= ~RADEON_SPECULAR_ENABLE
;
708 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
711 if (ctx
->Light
.Enabled
&&
712 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
713 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
714 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
715 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
716 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
717 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
718 p
|= RADEON_SPECULAR_ENABLE
;
719 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
720 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
722 else if (ctx
->Light
.Enabled
) {
723 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
724 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
725 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
726 } else if (ctx
->Fog
.ColorSumEnabled
) {
727 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
728 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
729 p
|= RADEON_SPECULAR_ENABLE
;
731 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
734 if (ctx
->Fog
.Enabled
) {
735 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
736 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
738 /* Bizzare: have to leave lighting enabled to get fog.
740 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
743 if ( ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) {
744 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
746 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
749 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
750 RADEON_STATECHANGE( rmesa
, ctx
);
751 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
754 /* Update vertex/render formats
756 if (rmesa
->TclFallback
) {
757 radeonChooseRenderState( ctx
);
758 radeonChooseVertexState( ctx
);
763 /* =============================================================
768 /* Update on colormaterial, material emmissive/ambient,
769 * lightmodel.globalambient
771 static void update_global_ambient( GLcontext
*ctx
)
773 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
774 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
776 /* Need to do more if both emmissive & ambient are PREMULT:
778 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
779 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
780 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
782 COPY_3V( &fcmd
[GLT_RED
],
783 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
784 ACC_SCALE_3V( &fcmd
[GLT_RED
],
785 ctx
->Light
.Model
.Ambient
,
786 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
790 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
793 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
796 /* Update on change to
800 * - colormaterial enabled
801 * - colormaterial bitmask
803 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
805 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
807 /* fprintf(stderr, "%s\n", __FUNCTION__); */
810 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
811 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
812 GLuint bitmask
= ctx
->Light
.ColorMaterialBitmask
;
813 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
815 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
816 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
817 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
819 if (!ctx
->Light
.ColorMaterialEnabled
)
822 if ((bitmask
& MAT_BIT_FRONT_AMBIENT
) == 0)
823 SELF_SCALE_3V( &fcmd
[LIT_AMBIENT_RED
], mat
[MAT_ATTRIB_FRONT_AMBIENT
] );
825 if ((bitmask
& MAT_BIT_FRONT_DIFFUSE
) == 0)
826 SELF_SCALE_3V( &fcmd
[LIT_DIFFUSE_RED
], mat
[MAT_ATTRIB_FRONT_DIFFUSE
] );
828 if ((bitmask
& MAT_BIT_FRONT_SPECULAR
) == 0)
829 SELF_SCALE_3V( &fcmd
[LIT_SPECULAR_RED
], mat
[MAT_ATTRIB_FRONT_SPECULAR
] );
831 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
835 /* Also fallback for asym colormaterial mode in twoside lighting...
837 static void check_twoside_fallback( GLcontext
*ctx
)
839 GLboolean fallback
= GL_FALSE
;
842 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
843 if (ctx
->Light
.ColorMaterialEnabled
&&
844 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
845 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
848 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
849 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
850 ctx
->Light
.Material
.Attrib
[i
+1],
851 sizeof(GLfloat
)*4) != 0) {
858 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
862 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
864 if (ctx
->Light
.ColorMaterialEnabled
) {
865 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
866 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
867 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
869 /* Default to PREMULT:
871 light_model_ctl1
&= ~((0xf << RADEON_EMISSIVE_SOURCE_SHIFT
) |
872 (0xf << RADEON_AMBIENT_SOURCE_SHIFT
) |
873 (0xf << RADEON_DIFFUSE_SOURCE_SHIFT
) |
874 (0xf << RADEON_SPECULAR_SOURCE_SHIFT
));
876 if (mask
& MAT_BIT_FRONT_EMISSION
) {
877 light_model_ctl1
|= (3 <<
878 RADEON_EMISSIVE_SOURCE_SHIFT
);
881 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
882 light_model_ctl1
|= (3 <<
883 RADEON_AMBIENT_SOURCE_SHIFT
);
886 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
887 light_model_ctl1
|= (3 <<
888 RADEON_DIFFUSE_SOURCE_SHIFT
);
891 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
892 light_model_ctl1
|= (3 <<
893 RADEON_SPECULAR_SOURCE_SHIFT
);
896 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
899 RADEON_STATECHANGE( rmesa
, tcl
);
900 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
902 for (p
= 0 ; p
< MAX_LIGHTS
; p
++)
903 update_light_colors( ctx
, p
);
904 update_global_ambient( ctx
);
908 check_twoside_fallback( ctx
);
911 void radeonUpdateMaterial( GLcontext
*ctx
)
913 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
914 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
915 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
919 if (ctx
->Light
.ColorMaterialEnabled
)
920 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
922 if (RADEON_DEBUG
& DEBUG_STATE
)
923 fprintf(stderr
, "%s\n", __FUNCTION__
);
926 if (mask
& MAT_BIT_FRONT_EMISSION
) {
927 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
928 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
929 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
930 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
932 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
933 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
934 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
935 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
936 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
938 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
939 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
940 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
941 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
942 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
944 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
945 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
946 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
947 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
948 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
950 if (mask
& MAT_BIT_FRONT_SHININESS
) {
951 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
954 if (RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
)) {
955 for (p
= 0 ; p
< MAX_LIGHTS
; p
++)
956 update_light_colors( ctx
, p
);
958 check_twoside_fallback( ctx
);
959 update_global_ambient( ctx
);
961 else if (RADEON_DEBUG
& (DEBUG_PRIMS
|DEBUG_STATE
))
962 fprintf(stderr
, "%s: Elided noop material call\n", __FUNCTION__
);
967 * _MESA_NEW_NEED_EYE_COORDS
969 * Uses derived state from mesa:
978 * which are calculated in light.c and are correct for the current
979 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
980 * and _MESA_NEW_NEED_EYE_COORDS.
982 static void update_light( GLcontext
*ctx
)
984 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
986 /* Have to check these, or have an automatic shortcircuit mechanism
987 * to remove noop statechanges. (Or just do a better job on the
991 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
993 if (ctx
->_NeedEyeCoords
)
994 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
996 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
999 /* Leave this test disabled: (unexplained q3 lockup) (even with
1002 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
1004 RADEON_STATECHANGE( rmesa
, tcl
);
1005 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
1010 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
1011 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1012 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1013 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1014 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1015 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1020 if (ctx
->Light
.Enabled
) {
1022 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1023 if (ctx
->Light
.Light
[p
].Enabled
) {
1024 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1025 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
1027 if (l
->EyePosition
[3] == 0.0) {
1028 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1029 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1030 fcmd
[LIT_POSITION_W
] = 0;
1031 fcmd
[LIT_DIRECTION_W
] = 0;
1033 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1034 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1035 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1036 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1037 fcmd
[LIT_DIRECTION_W
] = 0;
1040 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1046 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
1047 GLenum pname
, const GLfloat
*params
)
1049 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1050 GLint p
= light
- GL_LIGHT0
;
1051 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1052 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1059 update_light_colors( ctx
, p
);
1062 case GL_SPOT_DIRECTION
:
1063 /* picked up in update_light */
1067 /* positions picked up in update_light, but can do flag here */
1069 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1071 /* FIXME: Set RANGE_ATTEN only when needed */
1073 flag
= RADEON_LIGHT_1_IS_LOCAL
;
1075 flag
= RADEON_LIGHT_0_IS_LOCAL
;
1077 RADEON_STATECHANGE(rmesa
, tcl
);
1078 if (l
->EyePosition
[3] != 0.0F
)
1079 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1081 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1085 case GL_SPOT_EXPONENT
:
1086 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1087 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1090 case GL_SPOT_CUTOFF
: {
1091 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
1092 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1094 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1095 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1097 RADEON_STATECHANGE(rmesa
, tcl
);
1098 if (l
->SpotCutoff
!= 180.0F
)
1099 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1101 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1106 case GL_CONSTANT_ATTENUATION
:
1107 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1108 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1110 case GL_LINEAR_ATTENUATION
:
1111 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1112 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1114 case GL_QUADRATIC_ATTENUATION
:
1115 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1116 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1122 /* Set RANGE_ATTEN only when needed */
1125 case GL_LINEAR_ATTENUATION
:
1126 case GL_QUADRATIC_ATTENUATION
:
1129 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1132 flag
= RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
;
1134 flag
= RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1136 RADEON_STATECHANGE(rmesa
, tcl
);
1137 if (l
->EyePosition
[3] != 0.0F
&&
1138 (l
->LinearAttenuation
!= 0.0F
|| l
->QuadraticAttenuation
!= 0.0F
))
1139 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1141 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1152 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1153 const GLfloat
*param
)
1155 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1158 case GL_LIGHT_MODEL_AMBIENT
:
1159 update_global_ambient( ctx
);
1162 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1163 RADEON_STATECHANGE( rmesa
, tcl
);
1164 if (ctx
->Light
.Model
.LocalViewer
)
1165 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1167 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1170 case GL_LIGHT_MODEL_TWO_SIDE
:
1171 RADEON_STATECHANGE( rmesa
, tcl
);
1172 if (ctx
->Light
.Model
.TwoSide
)
1173 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1175 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1177 check_twoside_fallback( ctx
);
1179 if (rmesa
->TclFallback
) {
1180 radeonChooseRenderState( ctx
);
1181 radeonChooseVertexState( ctx
);
1185 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1186 radeonUpdateSpecular(ctx
);
1194 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1196 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1197 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1199 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1200 RADEON_ALPHA_SHADE_MASK
|
1201 RADEON_SPECULAR_SHADE_MASK
|
1202 RADEON_FOG_SHADE_MASK
);
1206 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1207 RADEON_ALPHA_SHADE_FLAT
|
1208 RADEON_SPECULAR_SHADE_FLAT
|
1209 RADEON_FOG_SHADE_FLAT
);
1212 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1213 RADEON_ALPHA_SHADE_GOURAUD
|
1214 RADEON_SPECULAR_SHADE_GOURAUD
|
1215 RADEON_FOG_SHADE_GOURAUD
);
1221 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1222 RADEON_STATECHANGE( rmesa
, set
);
1223 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1228 /* =============================================================
1232 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1234 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1235 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1236 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1238 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1239 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1240 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1241 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1242 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1245 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1247 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1250 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1251 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1252 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1254 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1255 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1256 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1257 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1258 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1264 /* =============================================================
1268 static void radeonStencilFunc( GLcontext
*ctx
, GLenum func
,
1269 GLint ref
, GLuint mask
)
1271 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1272 GLuint refmask
= ((ctx
->Stencil
.Ref
[0] << RADEON_STENCIL_REF_SHIFT
) |
1273 (ctx
->Stencil
.ValueMask
[0] << RADEON_STENCIL_MASK_SHIFT
));
1275 RADEON_STATECHANGE( rmesa
, ctx
);
1276 RADEON_STATECHANGE( rmesa
, msk
);
1278 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1279 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1280 RADEON_STENCIL_VALUE_MASK
);
1282 switch ( ctx
->Stencil
.Function
[0] ) {
1284 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1287 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1290 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1293 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1296 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1299 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1305 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1309 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1312 static void radeonStencilMask( GLcontext
*ctx
, GLuint mask
)
1314 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1316 RADEON_STATECHANGE( rmesa
, msk
);
1317 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1318 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1319 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
);
1322 static void radeonStencilOp( GLcontext
*ctx
, GLenum fail
,
1323 GLenum zfail
, GLenum zpass
)
1325 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1327 RADEON_STATECHANGE( rmesa
, ctx
);
1328 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1329 RADEON_STENCIL_ZFAIL_MASK
|
1330 RADEON_STENCIL_ZPASS_MASK
);
1332 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1334 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1337 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1340 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1343 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1346 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1349 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1353 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1355 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1358 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1361 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1364 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1367 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1370 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1374 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1376 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1379 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1382 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1385 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1388 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1391 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1396 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1398 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1400 rmesa
->state
.stencil
.clear
=
1401 ((GLuint
) ctx
->Stencil
.Clear
|
1402 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1403 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
));
1407 /* =============================================================
1408 * Window position and viewport transformation
1412 * To correctly position primitives:
1414 #define SUBPIXEL_X 0.125
1415 #define SUBPIXEL_Y 0.125
1417 void radeonUpdateWindow( GLcontext
*ctx
)
1419 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1420 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1421 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1422 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1423 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1425 GLfloat sx
= v
[MAT_SX
];
1426 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1427 GLfloat sy
= - v
[MAT_SY
];
1428 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1429 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1430 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1431 RADEON_FIREVERTICES( rmesa
);
1432 RADEON_STATECHANGE( rmesa
, vpt
);
1434 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = *(GLuint
*)&sx
;
1435 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1436 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = *(GLuint
*)&sy
;
1437 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1438 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = *(GLuint
*)&sz
;
1439 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = *(GLuint
*)&tz
;
1444 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1445 GLsizei width
, GLsizei height
)
1447 /* Don't pipeline viewport changes, conflict with window offset
1448 * setting below. Could apply deltas to rescue pipelined viewport
1449 * values, or keep the originals hanging around.
1451 RADEON_FIREVERTICES( RADEON_CONTEXT(ctx
) );
1452 radeonUpdateWindow( ctx
);
1455 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1458 radeonUpdateWindow( ctx
);
1461 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1463 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1464 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1465 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1466 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1467 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1469 GLfloat tx
= v
[MAT_TX
] + xoffset
;
1470 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
;
1472 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != *(GLuint
*)&tx
||
1473 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != *(GLuint
*)&ty
)
1475 /* Note: this should also modify whatever data the context reset
1478 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1479 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1481 /* update polygon stipple x/y screen offset */
1484 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1486 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1487 RADEON_STIPPLE_Y_OFFSET_MASK
);
1489 /* add magic offsets, then invert */
1490 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1491 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1492 & RADEON_STIPPLE_COORD_MASK
);
1494 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1495 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1497 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1498 RADEON_STATECHANGE( rmesa
, msc
);
1499 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1504 radeonUpdateScissor( ctx
);
1509 /* =============================================================
1513 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1515 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1517 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1518 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1519 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1520 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1521 rmesa
->state
.color
.clear
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
1522 c
[0], c
[1], c
[2], c
[3] );
1526 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1528 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1529 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1533 static GLuint radeon_rop_tab
[] = {
1536 RADEON_ROP_AND_REVERSE
,
1538 RADEON_ROP_AND_INVERTED
,
1545 RADEON_ROP_OR_REVERSE
,
1546 RADEON_ROP_COPY_INVERTED
,
1547 RADEON_ROP_OR_INVERTED
,
1552 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1554 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1555 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1559 RADEON_STATECHANGE( rmesa
, msk
);
1560 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1564 void radeonSetCliprects( radeonContextPtr rmesa
, GLenum mode
)
1566 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1570 rmesa
->numClipRects
= dPriv
->numClipRects
;
1571 rmesa
->pClipRects
= (XF86DRIClipRectPtr
)dPriv
->pClipRects
;
1574 /* Can't ignore 2d windows if we are page flipping.
1576 if ( dPriv
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1577 rmesa
->numClipRects
= dPriv
->numClipRects
;
1578 rmesa
->pClipRects
= (XF86DRIClipRectPtr
)dPriv
->pClipRects
;
1581 rmesa
->numClipRects
= dPriv
->numBackClipRects
;
1582 rmesa
->pClipRects
= (XF86DRIClipRectPtr
)dPriv
->pBackClipRects
;
1586 fprintf(stderr
, "bad mode in radeonSetCliprects\n");
1590 if (rmesa
->state
.scissor
.enabled
)
1591 radeonRecalcScissorRects( rmesa
);
1595 static void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
1597 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1599 if (RADEON_DEBUG
& DEBUG_DRI
)
1600 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1601 _mesa_lookup_enum_by_nr( mode
));
1603 RADEON_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1606 * _DrawDestMask is easier to cope with than <mode>.
1608 switch ( ctx
->Color
._DrawDestMask
) {
1609 case FRONT_LEFT_BIT
:
1610 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1611 radeonSetCliprects( rmesa
, GL_FRONT_LEFT
);
1614 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1615 radeonSetCliprects( rmesa
, GL_BACK_LEFT
);
1618 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
1619 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1623 /* We want to update the s/w rast state too so that r200SetBuffer()
1626 _swrast_DrawBuffer(ctx
, mode
);
1628 RADEON_STATECHANGE( rmesa
, ctx
);
1629 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
] = (rmesa
->state
.color
.drawOffset
&
1630 RADEON_COLOROFFSET_MASK
);
1631 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = rmesa
->state
.color
.drawPitch
;
1634 static void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
1636 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1640 /* =============================================================
1641 * State enable/disable
1644 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1646 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1649 if ( RADEON_DEBUG
& DEBUG_STATE
)
1650 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1651 _mesa_lookup_enum_by_nr( cap
),
1652 state
? "GL_TRUE" : "GL_FALSE" );
1655 /* Fast track this one...
1663 RADEON_STATECHANGE( rmesa
, ctx
);
1665 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1667 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1672 RADEON_STATECHANGE( rmesa
, ctx
);
1674 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1676 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1678 if ( ctx
->Color
.ColorLogicOpEnabled
) {
1679 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1681 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1684 /* Catch a possible fallback:
1687 ctx
->Driver
.BlendEquation( ctx
, ctx
->Color
.BlendEquation
);
1688 ctx
->Driver
.BlendFunc( ctx
, ctx
->Color
.BlendSrcRGB
,
1689 ctx
->Color
.BlendDstRGB
);
1692 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1693 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1697 case GL_CLIP_PLANE0
:
1698 case GL_CLIP_PLANE1
:
1699 case GL_CLIP_PLANE2
:
1700 case GL_CLIP_PLANE3
:
1701 case GL_CLIP_PLANE4
:
1702 case GL_CLIP_PLANE5
:
1703 p
= cap
-GL_CLIP_PLANE0
;
1704 RADEON_STATECHANGE( rmesa
, tcl
);
1706 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1707 radeonClipPlane( ctx
, cap
, NULL
);
1710 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1714 case GL_COLOR_MATERIAL
:
1715 radeonColorMaterial( ctx
, 0, 0 );
1717 radeonUpdateMaterial( ctx
);
1721 radeonCullFace( ctx
, 0 );
1725 RADEON_STATECHANGE(rmesa
, ctx
);
1727 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1729 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1734 RADEON_STATECHANGE(rmesa
, ctx
);
1736 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1738 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1743 RADEON_STATECHANGE(rmesa
, ctx
);
1745 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1746 radeonFogfv( ctx
, GL_FOG_MODE
, 0 );
1748 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1749 RADEON_STATECHANGE(rmesa
, tcl
);
1750 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1752 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1753 if (rmesa
->TclFallback
)
1754 radeonChooseVertexState( ctx
);
1755 _mesa_allow_light_in_model( ctx
, !state
);
1766 RADEON_STATECHANGE(rmesa
, tcl
);
1767 p
= cap
- GL_LIGHT0
;
1769 flag
= (RADEON_LIGHT_1_ENABLE
|
1770 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1771 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1773 flag
= (RADEON_LIGHT_0_ENABLE
|
1774 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1775 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1778 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1780 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1784 update_light_colors( ctx
, p
);
1788 RADEON_STATECHANGE(rmesa
, tcl
);
1789 radeonUpdateSpecular(ctx
);
1790 check_twoside_fallback( ctx
);
1793 case GL_LINE_SMOOTH
:
1794 RADEON_STATECHANGE( rmesa
, ctx
);
1796 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1798 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1802 case GL_LINE_STIPPLE
:
1803 RADEON_STATECHANGE( rmesa
, ctx
);
1805 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1807 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1811 case GL_COLOR_LOGIC_OP
:
1812 RADEON_STATECHANGE( rmesa
, ctx
);
1814 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1816 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1821 RADEON_STATECHANGE( rmesa
, tcl
);
1823 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1825 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1829 case GL_POLYGON_OFFSET_POINT
:
1830 if (rmesa
->dri
.drmMinor
== 1) {
1831 radeonChooseRenderState( ctx
);
1834 RADEON_STATECHANGE( rmesa
, set
);
1836 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1838 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1843 case GL_POLYGON_OFFSET_LINE
:
1844 if (rmesa
->dri
.drmMinor
== 1) {
1845 radeonChooseRenderState( ctx
);
1848 RADEON_STATECHANGE( rmesa
, set
);
1850 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1852 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1857 case GL_POLYGON_OFFSET_FILL
:
1858 if (rmesa
->dri
.drmMinor
== 1) {
1859 radeonChooseRenderState( ctx
);
1862 RADEON_STATECHANGE( rmesa
, set
);
1864 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1866 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1871 case GL_POLYGON_SMOOTH
:
1872 RADEON_STATECHANGE( rmesa
, ctx
);
1874 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1876 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1880 case GL_POLYGON_STIPPLE
:
1881 RADEON_STATECHANGE(rmesa
, ctx
);
1883 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1885 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1889 case GL_RESCALE_NORMAL_EXT
: {
1890 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1891 RADEON_STATECHANGE( rmesa
, tcl
);
1893 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1895 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1900 case GL_SCISSOR_TEST
:
1901 RADEON_FIREVERTICES( rmesa
);
1902 rmesa
->state
.scissor
.enabled
= state
;
1903 radeonUpdateScissor( ctx
);
1906 case GL_STENCIL_TEST
:
1907 if ( rmesa
->state
.stencil
.hwBuffer
) {
1908 RADEON_STATECHANGE( rmesa
, ctx
);
1910 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1912 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1915 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1919 case GL_TEXTURE_GEN_Q
:
1920 case GL_TEXTURE_GEN_R
:
1921 case GL_TEXTURE_GEN_S
:
1922 case GL_TEXTURE_GEN_T
:
1923 /* Picked up in radeonUpdateTextureState.
1925 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1928 case GL_COLOR_SUM_EXT
:
1929 radeonUpdateSpecular ( ctx
);
1938 static void radeonLightingSpaceChange( GLcontext
*ctx
)
1940 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1942 RADEON_STATECHANGE( rmesa
, tcl
);
1944 if (RADEON_DEBUG
& DEBUG_STATE
)
1945 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1946 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1948 if (ctx
->_NeedEyeCoords
)
1949 tmp
= ctx
->Transform
.RescaleNormals
;
1951 tmp
= !ctx
->Transform
.RescaleNormals
;
1954 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1956 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1959 if (RADEON_DEBUG
& DEBUG_STATE
)
1960 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1961 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1964 /* =============================================================
1965 * Deferred state management - matrices, textures, other?
1971 static void upload_matrix( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
1973 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1977 for (i
= 0 ; i
< 4 ; i
++) {
1981 *dest
++ = src
[i
+12];
1984 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1987 static void upload_matrix_t( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
1989 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1990 memcpy(dest
, src
, 16*sizeof(float));
1991 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1995 static void update_texturematrix( GLcontext
*ctx
)
1997 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
1998 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
1999 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2002 rmesa
->TexMatEnabled
= 0;
2004 for (unit
= 0 ; unit
< 2; unit
++) {
2005 if (!ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2007 else if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2008 GLuint inputshift
= RADEON_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
2010 rmesa
->TexMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2011 RADEON_TEXMAT_0_ENABLE
) << unit
;
2013 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2014 /* Need to preconcatenate any active texgen
2015 * obj/eyeplane matrices:
2017 _math_matrix_mul_matrix( &rmesa
->tmpmat
,
2018 &rmesa
->TexGenMatrix
[unit
],
2019 ctx
->TextureMatrixStack
[unit
].Top
);
2020 upload_matrix( rmesa
, rmesa
->tmpmat
.m
, TEXMAT_0
+unit
);
2023 rmesa
->TexMatEnabled
|=
2024 (RADEON_TEXGEN_INPUT_TEXCOORD_0
+unit
) << inputshift
;
2025 upload_matrix( rmesa
, ctx
->TextureMatrixStack
[unit
].Top
->m
,
2029 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2030 upload_matrix( rmesa
, rmesa
->TexGenMatrix
[unit
].m
,
2036 tpc
= (rmesa
->TexMatEnabled
| rmesa
->TexGenEnabled
);
2038 vs
&= ~((0xf << RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2039 (0xf << RADEON_TCL_TEX_1_OUTPUT_SHIFT
));
2041 if (tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
)
2042 vs
|= RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
;
2044 vs
|= RADEON_TCL_TEX_INPUT_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
;
2046 if (tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
)
2047 vs
|= RADEON_TCL_TEX_COMPUTED_TEX_1
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
;
2049 vs
|= RADEON_TCL_TEX_INPUT_TEX_1
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
;
2051 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2052 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2054 RADEON_STATECHANGE(rmesa
, tcl
);
2055 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2056 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2062 void radeonValidateState( GLcontext
*ctx
)
2064 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2065 GLuint new_state
= rmesa
->NewGLState
;
2067 if (new_state
& _NEW_TEXTURE
) {
2068 radeonUpdateTextureState( ctx
);
2069 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2072 /* Need an event driven matrix update?
2074 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2075 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2077 /* Need these for lighting (shouldn't upload otherwise)
2079 if (new_state
& (_NEW_MODELVIEW
)) {
2080 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2081 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2084 /* Does this need to be triggered on eg. modelview for
2085 * texgen-derived objplane/eyeplane matrices?
2087 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2088 update_texturematrix( ctx
);
2091 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2092 update_light( ctx
);
2095 /* emit all active clip planes if projection matrix changes.
2097 if (new_state
& (_NEW_PROJECTION
)) {
2098 if (ctx
->Transform
.ClipPlanesEnabled
)
2099 radeonUpdateClipPlanes( ctx
);
2103 rmesa
->NewGLState
= 0;
2107 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2109 _swrast_InvalidateState( ctx
, new_state
);
2110 _swsetup_InvalidateState( ctx
, new_state
);
2111 _ac_InvalidateState( ctx
, new_state
);
2112 _tnl_InvalidateState( ctx
, new_state
);
2113 _ae_invalidate_state( ctx
, new_state
);
2114 RADEON_CONTEXT(ctx
)->NewGLState
|= new_state
;
2115 radeonVtxfmtInvalidate( ctx
);
2118 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2120 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2121 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2124 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2128 if (rmesa
->NewGLState
)
2129 radeonValidateState( ctx
);
2131 if (tnl
->vb
.Material
) {
2132 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2135 /* Run the pipeline.
2137 _tnl_run_pipeline( ctx
);
2139 if (tnl
->vb
.Material
) {
2140 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2141 radeonUpdateMaterial( ctx
); /* not needed any more? */
2146 /* Initialize the driver's state functions.
2148 void radeonInitStateFuncs( GLcontext
*ctx
)
2150 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2151 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2153 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2154 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2156 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2157 ctx
->Driver
.BlendEquation
= radeonBlendEquation
;
2158 ctx
->Driver
.BlendFunc
= radeonBlendFunc
;
2159 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2160 ctx
->Driver
.ClearColor
= radeonClearColor
;
2161 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2162 ctx
->Driver
.ClearIndex
= NULL
;
2163 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2164 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2165 ctx
->Driver
.ColorMask
= radeonColorMask
;
2166 ctx
->Driver
.CullFace
= radeonCullFace
;
2167 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2168 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2169 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2170 ctx
->Driver
.Enable
= radeonEnable
;
2171 ctx
->Driver
.Fogfv
= radeonFogfv
;
2172 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2173 ctx
->Driver
.Hint
= NULL
;
2174 ctx
->Driver
.IndexMask
= NULL
;
2175 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2176 ctx
->Driver
.Lightfv
= radeonLightfv
;
2177 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2178 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2179 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2180 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2182 if (RADEON_CONTEXT(ctx
)->dri
.drmMinor
> 1)
2183 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2185 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2186 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2187 ctx
->Driver
.Scissor
= radeonScissor
;
2188 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2189 ctx
->Driver
.StencilFunc
= radeonStencilFunc
;
2190 ctx
->Driver
.StencilMask
= radeonStencilMask
;
2191 ctx
->Driver
.StencilOp
= radeonStencilOp
;
2192 ctx
->Driver
.Viewport
= radeonViewport
;
2194 /* Pixel path fallbacks
2196 ctx
->Driver
.Accum
= _swrast_Accum
;
2197 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
2198 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
2199 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
2200 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
2202 /* Swrast hooks for imaging extensions:
2204 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
2205 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
2206 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
2207 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
2209 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2210 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;