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 "swrast/swrast.h"
45 #include "array_cache/acache.h"
47 #include "tnl/t_pipeline.h"
48 #include "main/light.h"
49 #include "swrast_setup/swrast_setup.h"
51 #include "radeon_context.h"
52 #include "radeon_ioctl.h"
53 #include "radeon_state.h"
54 #include "radeon_tcl.h"
55 #include "radeon_tex.h"
56 #include "radeon_swtcl.h"
57 #include "radeon_vtxfmt.h"
59 /* =============================================================
63 static void radeonAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
65 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
66 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
69 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
71 RADEON_STATECHANGE( rmesa
, ctx
);
73 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
74 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
78 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
81 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
84 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
87 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
90 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
93 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
96 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
99 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
103 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
106 static void radeonBlendEquationSeparate( GLcontext
*ctx
,
107 GLenum modeRGB
, GLenum modeA
)
109 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
110 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
111 GLboolean fallback
= GL_FALSE
;
113 assert( modeRGB
== modeA
);
118 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
121 case GL_FUNC_SUBTRACT
:
122 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
126 if (ctx
->Color
.BlendEnabled
)
129 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
133 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
135 RADEON_STATECHANGE( rmesa
, ctx
);
136 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
137 if ( ctx
->Color
._LogicOpEnabled
) {
138 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
140 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
145 static void radeonBlendFuncSeparate( GLcontext
*ctx
,
146 GLenum sfactorRGB
, GLenum dfactorRGB
,
147 GLenum sfactorA
, GLenum dfactorA
)
149 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
150 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
151 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
152 GLboolean fallback
= GL_FALSE
;
154 switch ( ctx
->Color
.BlendSrcRGB
) {
156 b
|= RADEON_SRC_BLEND_GL_ZERO
;
159 b
|= RADEON_SRC_BLEND_GL_ONE
;
162 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
164 case GL_ONE_MINUS_DST_COLOR
:
165 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
168 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
170 case GL_ONE_MINUS_SRC_COLOR
:
171 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
174 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
176 case GL_ONE_MINUS_SRC_ALPHA
:
177 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
180 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
182 case GL_ONE_MINUS_DST_ALPHA
:
183 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
185 case GL_SRC_ALPHA_SATURATE
:
186 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
188 case GL_CONSTANT_COLOR
:
189 case GL_ONE_MINUS_CONSTANT_COLOR
:
190 case GL_CONSTANT_ALPHA
:
191 case GL_ONE_MINUS_CONSTANT_ALPHA
:
192 if (ctx
->Color
.BlendEnabled
)
195 b
|= RADEON_SRC_BLEND_GL_ONE
;
201 switch ( ctx
->Color
.BlendDstRGB
) {
203 b
|= RADEON_DST_BLEND_GL_ZERO
;
206 b
|= RADEON_DST_BLEND_GL_ONE
;
209 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
211 case GL_ONE_MINUS_SRC_COLOR
:
212 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
215 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
217 case GL_ONE_MINUS_SRC_ALPHA
:
218 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
221 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
223 case GL_ONE_MINUS_DST_COLOR
:
224 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
227 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
229 case GL_ONE_MINUS_DST_ALPHA
:
230 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
232 case GL_CONSTANT_COLOR
:
233 case GL_ONE_MINUS_CONSTANT_COLOR
:
234 case GL_CONSTANT_ALPHA
:
235 case GL_ONE_MINUS_CONSTANT_ALPHA
:
236 if (ctx
->Color
.BlendEnabled
)
239 b
|= RADEON_DST_BLEND_GL_ZERO
;
245 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
247 RADEON_STATECHANGE( rmesa
, ctx
);
248 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
253 /* =============================================================
257 static void radeonDepthFunc( GLcontext
*ctx
, GLenum func
)
259 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
261 RADEON_STATECHANGE( rmesa
, ctx
);
262 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
264 switch ( ctx
->Depth
.Func
) {
266 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
269 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
272 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
275 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
278 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
281 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
284 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
287 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
293 static void radeonDepthMask( GLcontext
*ctx
, GLboolean flag
)
295 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
296 RADEON_STATECHANGE( rmesa
, ctx
);
298 if ( ctx
->Depth
.Mask
) {
299 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
301 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
305 static void radeonClearDepth( GLcontext
*ctx
, GLclampd d
)
307 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
308 GLuint format
= (rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &
309 RADEON_DEPTH_FORMAT_MASK
);
312 case RADEON_DEPTH_FORMAT_16BIT_INT_Z
:
313 rmesa
->state
.depth
.clear
= d
* 0x0000ffff;
315 case RADEON_DEPTH_FORMAT_24BIT_INT_Z
:
316 rmesa
->state
.depth
.clear
= d
* 0x00ffffff;
322 /* =============================================================
327 static void radeonFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
329 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
330 union { int i
; float f
; } c
, d
;
333 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
334 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
338 if (!ctx
->Fog
.Enabled
)
340 RADEON_STATECHANGE(rmesa
, tcl
);
341 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
342 switch (ctx
->Fog
.Mode
) {
344 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
345 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
350 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
351 d
.f
= 1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
355 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
357 d
.f
= ctx
->Fog
.Density
;
360 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
362 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
369 switch (ctx
->Fog
.Mode
) {
372 d
.f
= ctx
->Fog
.Density
;
376 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
384 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
385 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
389 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
390 d
.f
= 1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
395 RADEON_STATECHANGE( rmesa
, ctx
);
396 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
397 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] =
398 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
400 case GL_FOG_COORDINATE_SOURCE_EXT
:
408 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
409 RADEON_STATECHANGE( rmesa
, fog
);
410 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
411 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
416 /* =============================================================
421 static GLboolean
intersect_rect( XF86DRIClipRectPtr out
,
422 XF86DRIClipRectPtr a
,
423 XF86DRIClipRectPtr b
)
426 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
427 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
428 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
429 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
430 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
431 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
436 void radeonRecalcScissorRects( radeonContextPtr rmesa
)
438 XF86DRIClipRectPtr out
;
441 /* Grow cliprect store?
443 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
444 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
445 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
446 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
449 if (rmesa
->state
.scissor
.pClipRects
)
450 FREE(rmesa
->state
.scissor
.pClipRects
);
452 rmesa
->state
.scissor
.pClipRects
=
453 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
454 sizeof(XF86DRIClipRectRec
) );
456 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
457 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
462 out
= rmesa
->state
.scissor
.pClipRects
;
463 rmesa
->state
.scissor
.numClipRects
= 0;
465 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
466 if ( intersect_rect( out
,
467 &rmesa
->pClipRects
[i
],
468 &rmesa
->state
.scissor
.rect
) ) {
469 rmesa
->state
.scissor
.numClipRects
++;
476 static void radeonUpdateScissor( GLcontext
*ctx
)
478 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
480 if ( rmesa
->dri
.drawable
) {
481 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
483 int x
= ctx
->Scissor
.X
;
484 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
485 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
486 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
488 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
489 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
490 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
491 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
493 radeonRecalcScissorRects( rmesa
);
498 static void radeonScissor( GLcontext
*ctx
,
499 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
501 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
503 if ( ctx
->Scissor
.Enabled
) {
504 RADEON_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
505 radeonUpdateScissor( ctx
);
511 /* =============================================================
515 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
517 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
518 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
519 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
521 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
522 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
524 if ( ctx
->Polygon
.CullFlag
) {
525 switch ( ctx
->Polygon
.CullFaceMode
) {
527 s
&= ~RADEON_FFACE_SOLID
;
528 t
|= RADEON_CULL_FRONT
;
531 s
&= ~RADEON_BFACE_SOLID
;
532 t
|= RADEON_CULL_BACK
;
534 case GL_FRONT_AND_BACK
:
535 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
536 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
541 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
542 RADEON_STATECHANGE(rmesa
, set
);
543 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
546 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
547 RADEON_STATECHANGE(rmesa
, tcl
);
548 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
552 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
554 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
556 RADEON_STATECHANGE( rmesa
, set
);
557 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
559 RADEON_STATECHANGE( rmesa
, tcl
);
560 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
564 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
567 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
568 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
574 /* =============================================================
577 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
579 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
581 RADEON_STATECHANGE( rmesa
, lin
);
582 RADEON_STATECHANGE( rmesa
, set
);
584 /* Line width is stored in U6.4 format.
586 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
587 if ( widthf
> 1.0 ) {
588 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
590 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
594 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
596 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
598 RADEON_STATECHANGE( rmesa
, lin
);
599 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
600 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
604 /* =============================================================
607 static void radeonColorMask( GLcontext
*ctx
,
608 GLboolean r
, GLboolean g
,
609 GLboolean b
, GLboolean a
)
611 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
612 GLuint mask
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
613 ctx
->Color
.ColorMask
[RCOMP
],
614 ctx
->Color
.ColorMask
[GCOMP
],
615 ctx
->Color
.ColorMask
[BCOMP
],
616 ctx
->Color
.ColorMask
[ACOMP
] );
618 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
619 RADEON_STATECHANGE( rmesa
, msk
);
620 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
625 /* =============================================================
629 static void radeonPolygonOffset( GLcontext
*ctx
,
630 GLfloat factor
, GLfloat units
)
632 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
633 GLfloat constant
= units
* rmesa
->state
.depth
.scale
;
635 RADEON_STATECHANGE( rmesa
, zbs
);
636 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = *(GLuint
*)&factor
;
637 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = *(GLuint
*)&constant
;
640 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
642 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
644 drmRadeonStipple stipple
;
646 /* Must flip pattern upside down.
648 for ( i
= 0 ; i
< 32 ; i
++ ) {
649 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
652 /* TODO: push this into cmd mechanism
654 RADEON_FIREVERTICES( rmesa
);
655 LOCK_HARDWARE( rmesa
);
657 /* FIXME: Use window x,y offsets into stipple RAM.
659 stipple
.mask
= rmesa
->state
.stipple
.mask
;
660 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
661 &stipple
, sizeof(drmRadeonStipple
) );
662 UNLOCK_HARDWARE( rmesa
);
665 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
667 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
668 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
670 /* Can't generally do unfilled via tcl, but some good special
673 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
674 if (rmesa
->TclFallback
) {
675 radeonChooseRenderState( ctx
);
676 radeonChooseVertexState( ctx
);
681 /* =============================================================
682 * Rendering attributes
684 * We really don't want to recalculate all this every time we bind a
685 * texture. These things shouldn't change all that often, so it makes
686 * sense to break them out of the core texture state update routines.
689 /* Examine lighting and texture state to determine if separate specular
692 static void radeonUpdateSpecular( GLcontext
*ctx
)
694 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
695 CARD32 p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
697 RADEON_STATECHANGE( rmesa
, tcl
);
699 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
700 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
701 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
702 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
703 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
705 p
&= ~RADEON_SPECULAR_ENABLE
;
707 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
710 if (ctx
->Light
.Enabled
&&
711 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
712 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
713 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
714 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
715 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
716 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
717 p
|= RADEON_SPECULAR_ENABLE
;
718 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
719 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
721 else if (ctx
->Light
.Enabled
) {
722 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
723 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
724 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
725 } else if (ctx
->Fog
.ColorSumEnabled
) {
726 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
727 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
728 p
|= RADEON_SPECULAR_ENABLE
;
730 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
733 if (ctx
->Fog
.Enabled
) {
734 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
735 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
737 /* Bizzare: have to leave lighting enabled to get fog.
739 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
742 if (NEED_SECONDARY_COLOR(ctx
)) {
743 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
745 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
748 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
749 RADEON_STATECHANGE( rmesa
, ctx
);
750 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
753 /* Update vertex/render formats
755 if (rmesa
->TclFallback
) {
756 radeonChooseRenderState( ctx
);
757 radeonChooseVertexState( ctx
);
762 /* =============================================================
767 /* Update on colormaterial, material emmissive/ambient,
768 * lightmodel.globalambient
770 static void update_global_ambient( GLcontext
*ctx
)
772 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
773 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
775 /* Need to do more if both emmissive & ambient are PREMULT:
776 * Hope this is not needed for MULT
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 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
802 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
804 /* fprintf(stderr, "%s\n", __FUNCTION__); */
807 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
808 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
810 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
811 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
812 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
814 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
818 /* Also fallback for asym colormaterial mode in twoside lighting...
820 static void check_twoside_fallback( GLcontext
*ctx
)
822 GLboolean fallback
= GL_FALSE
;
825 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
826 if (ctx
->Light
.ColorMaterialEnabled
&&
827 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
828 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
831 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
832 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
833 ctx
->Light
.Material
.Attrib
[i
+1],
834 sizeof(GLfloat
)*4) != 0) {
841 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
845 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
847 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
848 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
850 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
851 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
852 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
853 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
855 if (ctx
->Light
.ColorMaterialEnabled
) {
856 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
858 if (mask
& MAT_BIT_FRONT_EMISSION
) {
859 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
860 RADEON_EMISSIVE_SOURCE_SHIFT
);
863 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
864 RADEON_EMISSIVE_SOURCE_SHIFT
);
867 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
868 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
869 RADEON_AMBIENT_SOURCE_SHIFT
);
872 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
873 RADEON_AMBIENT_SOURCE_SHIFT
);
876 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
877 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
878 RADEON_DIFFUSE_SOURCE_SHIFT
);
881 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
882 RADEON_DIFFUSE_SOURCE_SHIFT
);
885 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
886 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
887 RADEON_SPECULAR_SOURCE_SHIFT
);
890 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
891 RADEON_SPECULAR_SOURCE_SHIFT
);
897 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
898 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
899 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
900 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
903 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
904 RADEON_STATECHANGE( rmesa
, tcl
);
905 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
909 void radeonUpdateMaterial( GLcontext
*ctx
)
911 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
912 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
913 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
916 if (ctx
->Light
.ColorMaterialEnabled
)
917 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
919 if (RADEON_DEBUG
& DEBUG_STATE
)
920 fprintf(stderr
, "%s\n", __FUNCTION__
);
923 if (mask
& MAT_BIT_FRONT_EMISSION
) {
924 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
925 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
926 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
927 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
929 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
930 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
931 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
932 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
933 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
935 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
936 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
937 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
938 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
939 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
941 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
942 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
943 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
944 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
945 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
947 if (mask
& MAT_BIT_FRONT_SHININESS
) {
948 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
951 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
953 check_twoside_fallback( ctx
);
954 /* update_global_ambient( ctx );*/
959 * _MESA_NEW_NEED_EYE_COORDS
961 * Uses derived state from mesa:
970 * which are calculated in light.c and are correct for the current
971 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
972 * and _MESA_NEW_NEED_EYE_COORDS.
974 static void update_light( GLcontext
*ctx
)
976 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
978 /* Have to check these, or have an automatic shortcircuit mechanism
979 * to remove noop statechanges. (Or just do a better job on the
983 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
985 if (ctx
->_NeedEyeCoords
)
986 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
988 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
991 /* Leave this test disabled: (unexplained q3 lockup) (even with
994 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
996 RADEON_STATECHANGE( rmesa
, tcl
);
997 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
1002 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
1003 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1004 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1005 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1006 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1007 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1012 if (ctx
->Light
.Enabled
) {
1014 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1015 if (ctx
->Light
.Light
[p
].Enabled
) {
1016 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1017 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
1019 if (l
->EyePosition
[3] == 0.0) {
1020 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1021 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1022 fcmd
[LIT_POSITION_W
] = 0;
1023 fcmd
[LIT_DIRECTION_W
] = 0;
1025 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1026 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1027 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1028 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1029 fcmd
[LIT_DIRECTION_W
] = 0;
1032 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1038 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
1039 GLenum pname
, const GLfloat
*params
)
1041 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1042 GLint p
= light
- GL_LIGHT0
;
1043 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1044 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1051 update_light_colors( ctx
, p
);
1054 case GL_SPOT_DIRECTION
:
1055 /* picked up in update_light */
1059 /* positions picked up in update_light, but can do flag here */
1061 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1063 /* FIXME: Set RANGE_ATTEN only when needed */
1065 flag
= RADEON_LIGHT_1_IS_LOCAL
;
1067 flag
= RADEON_LIGHT_0_IS_LOCAL
;
1069 RADEON_STATECHANGE(rmesa
, tcl
);
1070 if (l
->EyePosition
[3] != 0.0F
)
1071 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1073 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1077 case GL_SPOT_EXPONENT
:
1078 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1079 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1082 case GL_SPOT_CUTOFF
: {
1083 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
1084 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1086 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1087 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1089 RADEON_STATECHANGE(rmesa
, tcl
);
1090 if (l
->SpotCutoff
!= 180.0F
)
1091 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1093 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1098 case GL_CONSTANT_ATTENUATION
:
1099 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1100 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1101 if ( params
[0] == 0.0 )
1102 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1104 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1106 case GL_LINEAR_ATTENUATION
:
1107 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1108 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1110 case GL_QUADRATIC_ATTENUATION
:
1111 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1112 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1118 /* Set RANGE_ATTEN only when needed */
1121 case GL_CONSTANT_ATTENUATION
:
1122 case GL_LINEAR_ATTENUATION
:
1123 case GL_QUADRATIC_ATTENUATION
:
1125 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1126 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1127 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1128 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1129 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1130 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1132 if ( l
->EyePosition
[3] == 0.0F
||
1133 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1134 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1135 /* Disable attenuation */
1136 icmd
[idx
] &= ~atten_flag
;
1138 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1139 /* Enable only constant portion of attenuation calculation */
1140 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1142 /* Enable full attenuation calculation */
1143 icmd
[idx
] &= ~atten_const_flag
;
1144 icmd
[idx
] |= atten_flag
;
1148 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1159 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1160 const GLfloat
*param
)
1162 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1165 case GL_LIGHT_MODEL_AMBIENT
:
1166 update_global_ambient( ctx
);
1169 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1170 RADEON_STATECHANGE( rmesa
, tcl
);
1171 if (ctx
->Light
.Model
.LocalViewer
)
1172 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1174 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1177 case GL_LIGHT_MODEL_TWO_SIDE
:
1178 RADEON_STATECHANGE( rmesa
, tcl
);
1179 if (ctx
->Light
.Model
.TwoSide
)
1180 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1182 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1184 check_twoside_fallback( ctx
);
1186 if (rmesa
->TclFallback
) {
1187 radeonChooseRenderState( ctx
);
1188 radeonChooseVertexState( ctx
);
1192 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1193 radeonUpdateSpecular(ctx
);
1201 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1203 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1204 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1206 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1207 RADEON_ALPHA_SHADE_MASK
|
1208 RADEON_SPECULAR_SHADE_MASK
|
1209 RADEON_FOG_SHADE_MASK
);
1213 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1214 RADEON_ALPHA_SHADE_FLAT
|
1215 RADEON_SPECULAR_SHADE_FLAT
|
1216 RADEON_FOG_SHADE_FLAT
);
1219 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1220 RADEON_ALPHA_SHADE_GOURAUD
|
1221 RADEON_SPECULAR_SHADE_GOURAUD
|
1222 RADEON_FOG_SHADE_GOURAUD
);
1228 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1229 RADEON_STATECHANGE( rmesa
, set
);
1230 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1235 /* =============================================================
1239 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1241 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1242 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1243 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1245 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1246 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1247 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1248 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1249 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1252 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1254 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1257 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1258 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1259 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1261 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1262 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1263 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1264 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1265 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1271 /* =============================================================
1275 static void radeonStencilFunc( GLcontext
*ctx
, 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
;
1319 static void radeonStencilMask( GLcontext
*ctx
, GLuint mask
)
1321 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1323 RADEON_STATECHANGE( rmesa
, msk
);
1324 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1325 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1326 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
);
1329 static void radeonStencilOp( GLcontext
*ctx
, GLenum fail
,
1330 GLenum zfail
, GLenum zpass
)
1332 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1334 RADEON_STATECHANGE( rmesa
, ctx
);
1335 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1336 RADEON_STENCIL_ZFAIL_MASK
|
1337 RADEON_STENCIL_ZPASS_MASK
);
1339 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1341 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1344 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1347 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1350 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1353 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1356 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1360 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1362 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1365 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1368 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1371 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1374 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1377 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1381 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1383 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1386 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1389 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1392 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1395 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1398 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1403 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1405 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1407 rmesa
->state
.stencil
.clear
=
1408 ((GLuint
) ctx
->Stencil
.Clear
|
1409 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1410 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
));
1414 /* =============================================================
1415 * Window position and viewport transformation
1419 * To correctly position primitives:
1421 #define SUBPIXEL_X 0.125
1422 #define SUBPIXEL_Y 0.125
1424 void radeonUpdateWindow( GLcontext
*ctx
)
1426 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1427 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1428 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1429 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1430 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1432 GLfloat sx
= v
[MAT_SX
];
1433 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1434 GLfloat sy
= - v
[MAT_SY
];
1435 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1436 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1437 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1438 RADEON_FIREVERTICES( rmesa
);
1439 RADEON_STATECHANGE( rmesa
, vpt
);
1441 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = *(GLuint
*)&sx
;
1442 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1443 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = *(GLuint
*)&sy
;
1444 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1445 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = *(GLuint
*)&sz
;
1446 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = *(GLuint
*)&tz
;
1451 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1452 GLsizei width
, GLsizei height
)
1454 /* Don't pipeline viewport changes, conflict with window offset
1455 * setting below. Could apply deltas to rescue pipelined viewport
1456 * values, or keep the originals hanging around.
1458 RADEON_FIREVERTICES( RADEON_CONTEXT(ctx
) );
1459 radeonUpdateWindow( ctx
);
1462 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1465 radeonUpdateWindow( ctx
);
1468 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1470 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1471 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1472 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1473 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1474 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1476 GLfloat tx
= v
[MAT_TX
] + xoffset
;
1477 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
;
1479 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != *(GLuint
*)&tx
||
1480 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != *(GLuint
*)&ty
)
1482 /* Note: this should also modify whatever data the context reset
1485 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1486 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1488 /* update polygon stipple x/y screen offset */
1491 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1493 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1494 RADEON_STIPPLE_Y_OFFSET_MASK
);
1496 /* add magic offsets, then invert */
1497 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1498 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1499 & RADEON_STIPPLE_COORD_MASK
);
1501 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1502 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1504 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1505 RADEON_STATECHANGE( rmesa
, msc
);
1506 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1511 radeonUpdateScissor( ctx
);
1516 /* =============================================================
1520 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1522 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1524 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1525 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1526 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1527 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1528 rmesa
->state
.color
.clear
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
1529 c
[0], c
[1], c
[2], c
[3] );
1533 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1535 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1536 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1540 static GLuint radeon_rop_tab
[] = {
1543 RADEON_ROP_AND_REVERSE
,
1545 RADEON_ROP_AND_INVERTED
,
1552 RADEON_ROP_OR_REVERSE
,
1553 RADEON_ROP_COPY_INVERTED
,
1554 RADEON_ROP_OR_INVERTED
,
1559 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1561 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1562 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1566 RADEON_STATECHANGE( rmesa
, msk
);
1567 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1571 void radeonSetCliprects( radeonContextPtr rmesa
, GLenum mode
)
1573 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1577 rmesa
->numClipRects
= dPriv
->numClipRects
;
1578 rmesa
->pClipRects
= (XF86DRIClipRectPtr
)dPriv
->pClipRects
;
1581 /* Can't ignore 2d windows if we are page flipping.
1583 if ( dPriv
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1584 rmesa
->numClipRects
= dPriv
->numClipRects
;
1585 rmesa
->pClipRects
= (XF86DRIClipRectPtr
)dPriv
->pClipRects
;
1588 rmesa
->numClipRects
= dPriv
->numBackClipRects
;
1589 rmesa
->pClipRects
= (XF86DRIClipRectPtr
)dPriv
->pBackClipRects
;
1593 fprintf(stderr
, "bad mode in radeonSetCliprects\n");
1597 if (rmesa
->state
.scissor
.enabled
)
1598 radeonRecalcScissorRects( rmesa
);
1602 static void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
1604 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1606 if (RADEON_DEBUG
& DEBUG_DRI
)
1607 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1608 _mesa_lookup_enum_by_nr( mode
));
1610 RADEON_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1613 * _DrawDestMask is easier to cope with than <mode>.
1615 switch ( ctx
->Color
._DrawDestMask
) {
1616 case FRONT_LEFT_BIT
:
1617 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1618 radeonSetCliprects( rmesa
, GL_FRONT_LEFT
);
1621 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1622 radeonSetCliprects( rmesa
, GL_BACK_LEFT
);
1625 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
1626 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1630 /* We want to update the s/w rast state too so that r200SetBuffer()
1633 _swrast_DrawBuffer(ctx
, mode
);
1635 RADEON_STATECHANGE( rmesa
, ctx
);
1636 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
] = ((rmesa
->state
.color
.drawOffset
+
1637 rmesa
->radeonScreen
->fbLocation
)
1638 & RADEON_COLOROFFSET_MASK
);
1639 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = rmesa
->state
.color
.drawPitch
;
1642 static void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
1644 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1648 /* =============================================================
1649 * State enable/disable
1652 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1654 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1657 if ( RADEON_DEBUG
& DEBUG_STATE
)
1658 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1659 _mesa_lookup_enum_by_nr( cap
),
1660 state
? "GL_TRUE" : "GL_FALSE" );
1663 /* Fast track this one...
1671 RADEON_STATECHANGE( rmesa
, ctx
);
1673 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1675 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1680 RADEON_STATECHANGE( rmesa
, ctx
);
1682 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1684 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1686 if ( ctx
->Color
._LogicOpEnabled
) {
1687 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1689 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1692 /* Catch a possible fallback:
1695 ctx
->Driver
.BlendEquationSeparate( ctx
,
1696 ctx
->Color
.BlendEquationRGB
,
1697 ctx
->Color
.BlendEquationA
);
1698 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1699 ctx
->Color
.BlendDstRGB
,
1700 ctx
->Color
.BlendSrcA
,
1701 ctx
->Color
.BlendDstA
);
1704 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1705 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1709 case GL_CLIP_PLANE0
:
1710 case GL_CLIP_PLANE1
:
1711 case GL_CLIP_PLANE2
:
1712 case GL_CLIP_PLANE3
:
1713 case GL_CLIP_PLANE4
:
1714 case GL_CLIP_PLANE5
:
1715 p
= cap
-GL_CLIP_PLANE0
;
1716 RADEON_STATECHANGE( rmesa
, tcl
);
1718 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1719 radeonClipPlane( ctx
, cap
, NULL
);
1722 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1726 case GL_COLOR_MATERIAL
:
1727 radeonColorMaterial( ctx
, 0, 0 );
1728 radeonUpdateMaterial( ctx
);
1732 radeonCullFace( ctx
, 0 );
1736 RADEON_STATECHANGE(rmesa
, ctx
);
1738 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1740 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1745 RADEON_STATECHANGE(rmesa
, ctx
);
1747 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1748 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1750 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1751 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1756 RADEON_STATECHANGE(rmesa
, ctx
);
1758 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1759 radeonFogfv( ctx
, GL_FOG_MODE
, 0 );
1761 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1762 RADEON_STATECHANGE(rmesa
, tcl
);
1763 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1765 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1766 if (rmesa
->TclFallback
)
1767 radeonChooseVertexState( ctx
);
1768 _mesa_allow_light_in_model( ctx
, !state
);
1779 RADEON_STATECHANGE(rmesa
, tcl
);
1780 p
= cap
- GL_LIGHT0
;
1782 flag
= (RADEON_LIGHT_1_ENABLE
|
1783 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1784 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1786 flag
= (RADEON_LIGHT_0_ENABLE
|
1787 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1788 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1791 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1793 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1797 update_light_colors( ctx
, p
);
1801 RADEON_STATECHANGE(rmesa
, tcl
);
1802 radeonUpdateSpecular(ctx
);
1803 check_twoside_fallback( ctx
);
1806 case GL_LINE_SMOOTH
:
1807 RADEON_STATECHANGE( rmesa
, ctx
);
1809 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1811 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1815 case GL_LINE_STIPPLE
:
1816 RADEON_STATECHANGE( rmesa
, ctx
);
1818 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1820 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1824 case GL_COLOR_LOGIC_OP
:
1825 RADEON_STATECHANGE( rmesa
, ctx
);
1826 if ( ctx
->Color
._LogicOpEnabled
) {
1827 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1829 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1834 RADEON_STATECHANGE( rmesa
, tcl
);
1836 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1838 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1842 case GL_POLYGON_OFFSET_POINT
:
1843 if (rmesa
->dri
.drmMinor
== 1) {
1844 radeonChooseRenderState( ctx
);
1847 RADEON_STATECHANGE( rmesa
, set
);
1849 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1851 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1856 case GL_POLYGON_OFFSET_LINE
:
1857 if (rmesa
->dri
.drmMinor
== 1) {
1858 radeonChooseRenderState( ctx
);
1861 RADEON_STATECHANGE( rmesa
, set
);
1863 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1865 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1870 case GL_POLYGON_OFFSET_FILL
:
1871 if (rmesa
->dri
.drmMinor
== 1) {
1872 radeonChooseRenderState( ctx
);
1875 RADEON_STATECHANGE( rmesa
, set
);
1877 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1879 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1884 case GL_POLYGON_SMOOTH
:
1885 RADEON_STATECHANGE( rmesa
, ctx
);
1887 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1889 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1893 case GL_POLYGON_STIPPLE
:
1894 RADEON_STATECHANGE(rmesa
, ctx
);
1896 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1898 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1902 case GL_RESCALE_NORMAL_EXT
: {
1903 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1904 RADEON_STATECHANGE( rmesa
, tcl
);
1906 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1908 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1913 case GL_SCISSOR_TEST
:
1914 RADEON_FIREVERTICES( rmesa
);
1915 rmesa
->state
.scissor
.enabled
= state
;
1916 radeonUpdateScissor( ctx
);
1919 case GL_STENCIL_TEST
:
1920 if ( rmesa
->state
.stencil
.hwBuffer
) {
1921 RADEON_STATECHANGE( rmesa
, ctx
);
1923 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1925 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1928 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1932 case GL_TEXTURE_GEN_Q
:
1933 case GL_TEXTURE_GEN_R
:
1934 case GL_TEXTURE_GEN_S
:
1935 case GL_TEXTURE_GEN_T
:
1936 /* Picked up in radeonUpdateTextureState.
1938 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1941 case GL_COLOR_SUM_EXT
:
1942 radeonUpdateSpecular ( ctx
);
1951 static void radeonLightingSpaceChange( GLcontext
*ctx
)
1953 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1955 RADEON_STATECHANGE( rmesa
, tcl
);
1957 if (RADEON_DEBUG
& DEBUG_STATE
)
1958 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1959 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1961 if (ctx
->_NeedEyeCoords
)
1962 tmp
= ctx
->Transform
.RescaleNormals
;
1964 tmp
= !ctx
->Transform
.RescaleNormals
;
1967 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1969 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1972 if (RADEON_DEBUG
& DEBUG_STATE
)
1973 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1974 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1977 /* =============================================================
1978 * Deferred state management - matrices, textures, other?
1984 static void upload_matrix( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
1986 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1990 for (i
= 0 ; i
< 4 ; i
++) {
1994 *dest
++ = src
[i
+12];
1997 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2000 static void upload_matrix_t( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2002 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2003 memcpy(dest
, src
, 16*sizeof(float));
2004 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2008 static void update_texturematrix( GLcontext
*ctx
)
2010 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
2011 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
2012 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2015 rmesa
->TexMatEnabled
= 0;
2017 for (unit
= 0 ; unit
< 2; unit
++) {
2018 if (!ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2020 else if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2021 GLuint inputshift
= RADEON_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
2023 rmesa
->TexMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2024 RADEON_TEXMAT_0_ENABLE
) << unit
;
2026 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2027 /* Need to preconcatenate any active texgen
2028 * obj/eyeplane matrices:
2030 _math_matrix_mul_matrix( &rmesa
->tmpmat
,
2031 &rmesa
->TexGenMatrix
[unit
],
2032 ctx
->TextureMatrixStack
[unit
].Top
);
2033 upload_matrix( rmesa
, rmesa
->tmpmat
.m
, TEXMAT_0
+unit
);
2036 rmesa
->TexMatEnabled
|=
2037 (RADEON_TEXGEN_INPUT_TEXCOORD_0
+unit
) << inputshift
;
2038 upload_matrix( rmesa
, ctx
->TextureMatrixStack
[unit
].Top
->m
,
2042 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2043 upload_matrix( rmesa
, rmesa
->TexGenMatrix
[unit
].m
,
2049 tpc
= (rmesa
->TexMatEnabled
| rmesa
->TexGenEnabled
);
2051 vs
&= ~((0xf << RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2052 (0xf << RADEON_TCL_TEX_1_OUTPUT_SHIFT
));
2054 if (tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
)
2055 vs
|= RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
;
2057 vs
|= RADEON_TCL_TEX_INPUT_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
;
2059 if (tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
)
2060 vs
|= RADEON_TCL_TEX_COMPUTED_TEX_1
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
;
2062 vs
|= RADEON_TCL_TEX_INPUT_TEX_1
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
;
2064 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2065 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2067 RADEON_STATECHANGE(rmesa
, tcl
);
2068 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2069 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2075 void radeonValidateState( GLcontext
*ctx
)
2077 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2078 GLuint new_state
= rmesa
->NewGLState
;
2080 if (new_state
& _NEW_TEXTURE
) {
2081 radeonUpdateTextureState( ctx
);
2082 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2085 /* Need an event driven matrix update?
2087 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2088 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2090 /* Need these for lighting (shouldn't upload otherwise)
2092 if (new_state
& (_NEW_MODELVIEW
)) {
2093 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2094 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2097 /* Does this need to be triggered on eg. modelview for
2098 * texgen-derived objplane/eyeplane matrices?
2100 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2101 update_texturematrix( ctx
);
2104 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2105 update_light( ctx
);
2108 /* emit all active clip planes if projection matrix changes.
2110 if (new_state
& (_NEW_PROJECTION
)) {
2111 if (ctx
->Transform
.ClipPlanesEnabled
)
2112 radeonUpdateClipPlanes( ctx
);
2116 rmesa
->NewGLState
= 0;
2120 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2122 _swrast_InvalidateState( ctx
, new_state
);
2123 _swsetup_InvalidateState( ctx
, new_state
);
2124 _ac_InvalidateState( ctx
, new_state
);
2125 _tnl_InvalidateState( ctx
, new_state
);
2126 _ae_invalidate_state( ctx
, new_state
);
2127 RADEON_CONTEXT(ctx
)->NewGLState
|= new_state
;
2128 radeonVtxfmtInvalidate( ctx
);
2132 /* A hack. Need a faster way to find this out.
2134 static GLboolean
check_material( GLcontext
*ctx
)
2136 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2139 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2140 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2142 if (tnl
->vb
.AttribPtr
[i
] &&
2143 tnl
->vb
.AttribPtr
[i
]->stride
)
2150 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2152 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2153 GLboolean has_material
;
2156 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2160 if (rmesa
->NewGLState
)
2161 radeonValidateState( ctx
);
2163 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2166 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2169 /* Run the pipeline.
2171 _tnl_run_pipeline( ctx
);
2174 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2179 /* Initialize the driver's state functions.
2181 void radeonInitStateFuncs( GLcontext
*ctx
)
2183 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2184 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2186 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2187 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2189 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2190 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2191 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2192 ctx
->Driver
.ClearColor
= radeonClearColor
;
2193 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2194 ctx
->Driver
.ClearIndex
= NULL
;
2195 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2196 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2197 ctx
->Driver
.ColorMask
= radeonColorMask
;
2198 ctx
->Driver
.CullFace
= radeonCullFace
;
2199 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2200 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2201 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2202 ctx
->Driver
.Enable
= radeonEnable
;
2203 ctx
->Driver
.Fogfv
= radeonFogfv
;
2204 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2205 ctx
->Driver
.Hint
= NULL
;
2206 ctx
->Driver
.IndexMask
= NULL
;
2207 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2208 ctx
->Driver
.Lightfv
= radeonLightfv
;
2209 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2210 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2211 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2212 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2214 if (RADEON_CONTEXT(ctx
)->dri
.drmMinor
> 1)
2215 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2217 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2218 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2219 ctx
->Driver
.Scissor
= radeonScissor
;
2220 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2221 ctx
->Driver
.StencilFunc
= radeonStencilFunc
;
2222 ctx
->Driver
.StencilMask
= radeonStencilMask
;
2223 ctx
->Driver
.StencilOp
= radeonStencilOp
;
2224 ctx
->Driver
.Viewport
= radeonViewport
;
2226 /* Pixel path fallbacks
2228 ctx
->Driver
.Accum
= _swrast_Accum
;
2229 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
2230 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
2231 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
2232 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
2234 /* Swrast hooks for imaging extensions:
2236 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
2237 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
2238 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
2239 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
2241 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2242 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;