2 /**************************************************************************
4 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 * Keith Whitwell <keith@tungstengraphics.com>
39 #include "api_arrayelt.h"
44 #include "swrast/swrast.h"
45 #include "array_cache/acache.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
51 #include "r200_context.h"
52 #include "r200_ioctl.h"
53 #include "r200_state.h"
56 #include "r200_swtcl.h"
57 #include "r200_vtxfmt.h"
60 /* =============================================================
64 static void r200AlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
66 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
67 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
70 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
72 R200_STATECHANGE( rmesa
, ctx
);
74 pp_misc
&= ~(R200_ALPHA_TEST_OP_MASK
| R200_REF_ALPHA_MASK
);
75 pp_misc
|= (refByte
& R200_REF_ALPHA_MASK
);
79 pp_misc
|= R200_ALPHA_TEST_FAIL
;
82 pp_misc
|= R200_ALPHA_TEST_LESS
;
85 pp_misc
|= R200_ALPHA_TEST_EQUAL
;
88 pp_misc
|= R200_ALPHA_TEST_LEQUAL
;
91 pp_misc
|= R200_ALPHA_TEST_GREATER
;
94 pp_misc
|= R200_ALPHA_TEST_NEQUAL
;
97 pp_misc
|= R200_ALPHA_TEST_GEQUAL
;
100 pp_misc
|= R200_ALPHA_TEST_PASS
;
104 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
107 static void r200BlendColor( GLcontext
*ctx
, const GLfloat cf
[4] )
110 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
111 R200_STATECHANGE( rmesa
, ctx
);
112 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
113 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
114 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
115 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
116 if (rmesa
->r200Screen
->drmSupportsBlendColor
)
117 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCOLOR
] = r200PackColor( 4, color
[0], color
[1], color
[2], color
[3] );
121 * Calculate the hardware blend factor setting. This same function is used
122 * for source and destination of both alpha and RGB.
125 * The hardware register value for the specified blend factor. This value
126 * will need to be shifted into the correct position for either source or
127 * destination factor.
130 * Since the two cases where source and destination are handled differently
131 * are essentially error cases, they should never happen. Determine if these
132 * cases can be removed.
134 static int blend_factor( GLenum factor
, GLboolean is_src
)
140 func
= R200_BLEND_GL_ZERO
;
143 func
= R200_BLEND_GL_ONE
;
146 func
= R200_BLEND_GL_DST_COLOR
;
148 case GL_ONE_MINUS_DST_COLOR
:
149 func
= R200_BLEND_GL_ONE_MINUS_DST_COLOR
;
152 func
= R200_BLEND_GL_SRC_COLOR
;
154 case GL_ONE_MINUS_SRC_COLOR
:
155 func
= R200_BLEND_GL_ONE_MINUS_SRC_COLOR
;
158 func
= R200_BLEND_GL_SRC_ALPHA
;
160 case GL_ONE_MINUS_SRC_ALPHA
:
161 func
= R200_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
164 func
= R200_BLEND_GL_DST_ALPHA
;
166 case GL_ONE_MINUS_DST_ALPHA
:
167 func
= R200_BLEND_GL_ONE_MINUS_DST_ALPHA
;
169 case GL_SRC_ALPHA_SATURATE
:
170 func
= (is_src
) ? R200_BLEND_GL_SRC_ALPHA_SATURATE
: R200_BLEND_GL_ZERO
;
172 case GL_CONSTANT_COLOR
:
173 func
= R200_BLEND_GL_CONST_COLOR
;
175 case GL_ONE_MINUS_CONSTANT_COLOR
:
176 func
= R200_BLEND_GL_ONE_MINUS_CONST_COLOR
;
178 case GL_CONSTANT_ALPHA
:
179 func
= R200_BLEND_GL_CONST_ALPHA
;
181 case GL_ONE_MINUS_CONSTANT_ALPHA
:
182 func
= R200_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
185 func
= (is_src
) ? R200_BLEND_GL_ONE
: R200_BLEND_GL_ZERO
;
191 * Sets both the blend equation and the blend function.
192 * This is done in a single
193 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
194 * change the interpretation of the blend function.
195 * Also, make sure that blend function and blend equation are set to their default
196 * value if color blending is not enabled, since at least blend equations GL_MIN
197 * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
200 static void r200_set_blend_state( GLcontext
* ctx
)
202 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
203 GLuint cntl
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &
204 ~(R200_ROP_ENABLE
| R200_ALPHA_BLEND_ENABLE
| R200_SEPARATE_ALPHA_ENABLE
);
206 int func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
207 (R200_BLEND_GL_ZERO
<< R200_DST_BLEND_SHIFT
);
208 int eqn
= R200_COMB_FCN_ADD_CLAMP
;
209 int funcA
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
210 (R200_BLEND_GL_ZERO
<< R200_DST_BLEND_SHIFT
);
211 int eqnA
= R200_COMB_FCN_ADD_CLAMP
;
213 R200_STATECHANGE( rmesa
, ctx
);
215 if (rmesa
->r200Screen
->drmSupportsBlendColor
) {
216 if (ctx
->Color
._LogicOpEnabled
) {
217 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
| R200_ROP_ENABLE
;
218 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ABLENDCNTL
] = eqn
| func
;
219 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CBLENDCNTL
] = eqn
| func
;
221 } else if (ctx
->Color
.BlendEnabled
) {
222 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
| R200_ALPHA_BLEND_ENABLE
| R200_SEPARATE_ALPHA_ENABLE
;
225 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
;
226 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ABLENDCNTL
] = eqn
| func
;
227 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CBLENDCNTL
] = eqn
| func
;
232 if (ctx
->Color
._LogicOpEnabled
) {
233 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
| R200_ROP_ENABLE
;
234 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = eqn
| func
;
236 } else if (ctx
->Color
.BlendEnabled
) {
237 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
| R200_ALPHA_BLEND_ENABLE
;
240 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
;
241 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = eqn
| func
;
246 func
= (blend_factor( ctx
->Color
.BlendSrcRGB
, GL_TRUE
) << R200_SRC_BLEND_SHIFT
) |
247 (blend_factor( ctx
->Color
.BlendDstRGB
, GL_FALSE
) << R200_DST_BLEND_SHIFT
);
249 switch(ctx
->Color
.BlendEquationRGB
) {
251 eqn
= R200_COMB_FCN_ADD_CLAMP
;
254 case GL_FUNC_SUBTRACT
:
255 eqn
= R200_COMB_FCN_SUB_CLAMP
;
258 case GL_FUNC_REVERSE_SUBTRACT
:
259 eqn
= R200_COMB_FCN_RSUB_CLAMP
;
263 eqn
= R200_COMB_FCN_MIN
;
264 func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
265 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
269 eqn
= R200_COMB_FCN_MAX
;
270 func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
271 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
275 fprintf( stderr
, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
276 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
280 if (!rmesa
->r200Screen
->drmSupportsBlendColor
) {
281 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = eqn
| func
;
285 funcA
= (blend_factor( ctx
->Color
.BlendSrcA
, GL_TRUE
) << R200_SRC_BLEND_SHIFT
) |
286 (blend_factor( ctx
->Color
.BlendDstA
, GL_FALSE
) << R200_DST_BLEND_SHIFT
);
288 switch(ctx
->Color
.BlendEquationA
) {
290 eqnA
= R200_COMB_FCN_ADD_CLAMP
;
293 case GL_FUNC_SUBTRACT
:
294 eqnA
= R200_COMB_FCN_SUB_CLAMP
;
297 case GL_FUNC_REVERSE_SUBTRACT
:
298 eqnA
= R200_COMB_FCN_RSUB_CLAMP
;
302 eqnA
= R200_COMB_FCN_MIN
;
303 funcA
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
304 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
308 eqnA
= R200_COMB_FCN_MAX
;
309 funcA
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
310 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
314 fprintf( stderr
, "[%s:%u] Invalid A blend equation (0x%04x).\n",
315 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
319 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ABLENDCNTL
] = eqnA
| funcA
;
320 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CBLENDCNTL
] = eqn
| func
;
324 static void r200BlendEquationSeparate( GLcontext
*ctx
,
325 GLenum modeRGB
, GLenum modeA
)
327 r200_set_blend_state( ctx
);
330 static void r200BlendFuncSeparate( GLcontext
*ctx
,
331 GLenum sfactorRGB
, GLenum dfactorRGB
,
332 GLenum sfactorA
, GLenum dfactorA
)
334 r200_set_blend_state( ctx
);
338 /* =============================================================
342 static void r200DepthFunc( GLcontext
*ctx
, GLenum func
)
344 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
346 R200_STATECHANGE( rmesa
, ctx
);
347 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~R200_Z_TEST_MASK
;
349 switch ( ctx
->Depth
.Func
) {
351 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_NEVER
;
354 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_LESS
;
357 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_EQUAL
;
360 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_LEQUAL
;
363 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_GREATER
;
366 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_NEQUAL
;
369 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_GEQUAL
;
372 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_ALWAYS
;
378 static void r200DepthMask( GLcontext
*ctx
, GLboolean flag
)
380 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
381 R200_STATECHANGE( rmesa
, ctx
);
383 if ( ctx
->Depth
.Mask
) {
384 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_WRITE_ENABLE
;
386 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~R200_Z_WRITE_ENABLE
;
391 /* =============================================================
396 static void r200Fogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
398 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
399 union { int i
; float f
; } c
, d
;
403 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
404 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
408 if (!ctx
->Fog
.Enabled
)
410 R200_STATECHANGE(rmesa
, tcl
);
411 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~R200_TCL_FOG_MASK
;
412 switch (ctx
->Fog
.Mode
) {
414 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_TCL_FOG_LINEAR
;
415 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
420 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
421 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
425 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_TCL_FOG_EXP
;
427 d
.f
= -ctx
->Fog
.Density
;
430 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_TCL_FOG_EXP2
;
432 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
439 switch (ctx
->Fog
.Mode
) {
442 d
.f
= -ctx
->Fog
.Density
;
446 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
454 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
455 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
459 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
460 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
465 R200_STATECHANGE( rmesa
, ctx
);
466 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
467 i
= r200PackColor( 4, col
[0], col
[1], col
[2], 0 );
468 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~R200_FOG_COLOR_MASK
;
469 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |= i
;
471 case GL_FOG_COORDINATE_SOURCE_EXT
:
479 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
480 R200_STATECHANGE( rmesa
, fog
);
481 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
482 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
487 /* =============================================================
492 static GLboolean
intersect_rect( drm_clip_rect_t
*out
,
497 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
498 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
499 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
500 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
501 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
502 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
507 void r200RecalcScissorRects( r200ContextPtr rmesa
)
509 drm_clip_rect_t
*out
;
512 /* Grow cliprect store?
514 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
515 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
516 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
517 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
520 if (rmesa
->state
.scissor
.pClipRects
)
521 FREE(rmesa
->state
.scissor
.pClipRects
);
523 rmesa
->state
.scissor
.pClipRects
=
524 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
525 sizeof(drm_clip_rect_t
) );
527 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
528 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
533 out
= rmesa
->state
.scissor
.pClipRects
;
534 rmesa
->state
.scissor
.numClipRects
= 0;
536 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
537 if ( intersect_rect( out
,
538 &rmesa
->pClipRects
[i
],
539 &rmesa
->state
.scissor
.rect
) ) {
540 rmesa
->state
.scissor
.numClipRects
++;
547 static void r200UpdateScissor( GLcontext
*ctx
)
549 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
551 if ( rmesa
->dri
.drawable
) {
552 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
554 int x
= ctx
->Scissor
.X
;
555 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
556 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
557 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
559 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
560 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
561 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
562 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
564 r200RecalcScissorRects( rmesa
);
569 static void r200Scissor( GLcontext
*ctx
,
570 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
572 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
574 if ( ctx
->Scissor
.Enabled
) {
575 R200_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
576 r200UpdateScissor( ctx
);
582 /* =============================================================
586 static void r200CullFace( GLcontext
*ctx
, GLenum unused
)
588 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
589 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
590 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
592 s
|= R200_FFACE_SOLID
| R200_BFACE_SOLID
;
593 t
&= ~(R200_CULL_FRONT
| R200_CULL_BACK
);
595 if ( ctx
->Polygon
.CullFlag
) {
596 switch ( ctx
->Polygon
.CullFaceMode
) {
598 s
&= ~R200_FFACE_SOLID
;
599 t
|= R200_CULL_FRONT
;
602 s
&= ~R200_BFACE_SOLID
;
605 case GL_FRONT_AND_BACK
:
606 s
&= ~(R200_FFACE_SOLID
| R200_BFACE_SOLID
);
607 t
|= (R200_CULL_FRONT
| R200_CULL_BACK
);
612 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
613 R200_STATECHANGE(rmesa
, set
);
614 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
617 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
618 R200_STATECHANGE(rmesa
, tcl
);
619 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
623 static void r200FrontFace( GLcontext
*ctx
, GLenum mode
)
625 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
627 R200_STATECHANGE( rmesa
, set
);
628 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_FFACE_CULL_DIR_MASK
;
630 R200_STATECHANGE( rmesa
, tcl
);
631 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~R200_CULL_FRONT_IS_CCW
;
635 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_FFACE_CULL_CW
;
638 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_FFACE_CULL_CCW
;
639 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_CULL_FRONT_IS_CCW
;
644 /* =============================================================
647 static void r200PointSize( GLcontext
*ctx
, GLfloat size
)
649 if (0) fprintf(stderr
, "%s: %f\n", __FUNCTION__
, size
);
652 /* =============================================================
655 static void r200LineWidth( GLcontext
*ctx
, GLfloat widthf
)
657 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
659 R200_STATECHANGE( rmesa
, lin
);
660 R200_STATECHANGE( rmesa
, set
);
662 /* Line width is stored in U6.4 format.
664 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] &= ~0xffff;
665 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] |= (GLuint
)(ctx
->Line
._Width
* 16.0);
667 if ( widthf
> 1.0 ) {
668 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_WIDELINE_ENABLE
;
670 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_WIDELINE_ENABLE
;
674 static void r200LineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
676 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
678 R200_STATECHANGE( rmesa
, lin
);
679 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
680 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
684 /* =============================================================
687 static void r200ColorMask( GLcontext
*ctx
,
688 GLboolean r
, GLboolean g
,
689 GLboolean b
, GLboolean a
)
691 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
692 GLuint mask
= r200PackColor( rmesa
->r200Screen
->cpp
,
693 ctx
->Color
.ColorMask
[RCOMP
],
694 ctx
->Color
.ColorMask
[GCOMP
],
695 ctx
->Color
.ColorMask
[BCOMP
],
696 ctx
->Color
.ColorMask
[ACOMP
] );
698 GLuint flag
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] & ~R200_PLANE_MASK_ENABLE
;
700 if (!(r
&& g
&& b
&& a
))
701 flag
|= R200_PLANE_MASK_ENABLE
;
703 if ( rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] != flag
) {
704 R200_STATECHANGE( rmesa
, ctx
);
705 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = flag
;
708 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
709 R200_STATECHANGE( rmesa
, msk
);
710 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
715 /* =============================================================
719 static void r200PolygonOffset( GLcontext
*ctx
,
720 GLfloat factor
, GLfloat units
)
722 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
723 GLfloat constant
= units
* rmesa
->state
.depth
.scale
;
728 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
730 R200_STATECHANGE( rmesa
, zbs
);
731 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = *(GLuint
*)&factor
;
732 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = *(GLuint
*)&constant
;
735 static void r200PolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
737 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
739 drm_radeon_stipple_t stipple
;
741 /* Must flip pattern upside down.
743 for ( i
= 0 ; i
< 32 ; i
++ ) {
744 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
747 /* TODO: push this into cmd mechanism
749 R200_FIREVERTICES( rmesa
);
750 LOCK_HARDWARE( rmesa
);
752 /* FIXME: Use window x,y offsets into stipple RAM.
754 stipple
.mask
= rmesa
->state
.stipple
.mask
;
755 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
756 &stipple
, sizeof(stipple
) );
757 UNLOCK_HARDWARE( rmesa
);
760 static void r200PolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
762 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
763 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
765 /* Can't generally do unfilled via tcl, but some good special
768 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_UNFILLED
, flag
);
769 if (rmesa
->TclFallback
) {
770 r200ChooseRenderState( ctx
);
771 r200ChooseVertexState( ctx
);
776 /* =============================================================
777 * Rendering attributes
779 * We really don't want to recalculate all this every time we bind a
780 * texture. These things shouldn't change all that often, so it makes
781 * sense to break them out of the core texture state update routines.
784 /* Examine lighting and texture state to determine if separate specular
787 static void r200UpdateSpecular( GLcontext
*ctx
)
789 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
790 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
792 R200_STATECHANGE( rmesa
, tcl
);
793 R200_STATECHANGE( rmesa
, vtx
);
795 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] &= ~(3<<R200_VTX_COLOR_0_SHIFT
);
796 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] &= ~(3<<R200_VTX_COLOR_1_SHIFT
);
797 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] &= ~R200_OUTPUT_COLOR_0
;
798 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] &= ~R200_OUTPUT_COLOR_1
;
799 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_LIGHTING_ENABLE
;
801 p
&= ~R200_SPECULAR_ENABLE
;
803 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_DIFFUSE_SPECULAR_COMBINE
;
806 if (ctx
->Light
.Enabled
&&
807 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
808 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
809 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
810 (R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
));
811 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_0
;
812 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_1
;
813 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LIGHTING_ENABLE
;
814 p
|= R200_SPECULAR_ENABLE
;
815 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &=
816 ~R200_DIFFUSE_SPECULAR_COMBINE
;
818 else if (ctx
->Light
.Enabled
) {
819 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
820 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
));
821 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_0
;
822 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LIGHTING_ENABLE
;
823 } else if (ctx
->Fog
.ColorSumEnabled
) {
824 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
825 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
826 (R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
));
827 p
|= R200_SPECULAR_ENABLE
;
829 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
830 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
));
833 if (ctx
->Fog
.Enabled
) {
834 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
835 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
));
836 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_1
;
839 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
840 R200_STATECHANGE( rmesa
, ctx
);
841 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
844 /* Update vertex/render formats
846 if (rmesa
->TclFallback
) {
847 r200ChooseRenderState( ctx
);
848 r200ChooseVertexState( ctx
);
853 /* =============================================================
858 /* Update on colormaterial, material emmissive/ambient,
859 * lightmodel.globalambient
861 static void update_global_ambient( GLcontext
*ctx
)
863 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
864 float *fcmd
= (float *)R200_DB_STATE( glt
);
866 /* Need to do more if both emmissive & ambient are PREMULT:
867 * I believe this is not nessary when using source_material. This condition thus
868 * will never happen currently, and the function has no dependencies on materials now
870 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
] &
871 ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT
) |
872 (3 << R200_FRONT_AMBIENT_SOURCE_SHIFT
))) == 0)
874 COPY_3V( &fcmd
[GLT_RED
],
875 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
876 ACC_SCALE_3V( &fcmd
[GLT_RED
],
877 ctx
->Light
.Model
.Ambient
,
878 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
882 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
885 R200_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
888 /* Update on change to
892 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
894 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
896 /* fprintf(stderr, "%s\n", __FUNCTION__); */
899 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
900 float *fcmd
= (float *)R200_DB_STATE( lit
[p
] );
902 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
903 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
904 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
906 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
910 static void r200ColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
912 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
913 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
];
914 light_model_ctl1
&= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT
) |
915 (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT
) |
916 (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT
) |
917 (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT
) |
918 (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT
) |
919 (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT
) |
920 (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT
) |
921 (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT
));
923 if (ctx
->Light
.ColorMaterialEnabled
) {
924 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
926 if (mask
& MAT_BIT_FRONT_EMISSION
) {
927 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
928 R200_FRONT_EMISSIVE_SOURCE_SHIFT
);
931 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
932 R200_FRONT_EMISSIVE_SOURCE_SHIFT
);
934 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
935 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
936 R200_FRONT_AMBIENT_SOURCE_SHIFT
);
939 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
940 R200_FRONT_AMBIENT_SOURCE_SHIFT
);
942 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
943 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
944 R200_FRONT_DIFFUSE_SOURCE_SHIFT
);
947 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
948 R200_FRONT_DIFFUSE_SOURCE_SHIFT
);
950 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
951 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
952 R200_FRONT_SPECULAR_SOURCE_SHIFT
);
955 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
956 R200_FRONT_SPECULAR_SOURCE_SHIFT
);
959 if (mask
& MAT_BIT_BACK_EMISSION
) {
960 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
961 R200_BACK_EMISSIVE_SOURCE_SHIFT
);
964 else light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
965 R200_BACK_EMISSIVE_SOURCE_SHIFT
);
967 if (mask
& MAT_BIT_BACK_AMBIENT
) {
968 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
969 R200_BACK_AMBIENT_SOURCE_SHIFT
);
971 else light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
972 R200_BACK_AMBIENT_SOURCE_SHIFT
);
974 if (mask
& MAT_BIT_BACK_DIFFUSE
) {
975 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
976 R200_BACK_DIFFUSE_SOURCE_SHIFT
);
978 else light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
979 R200_BACK_DIFFUSE_SOURCE_SHIFT
);
981 if (mask
& MAT_BIT_BACK_SPECULAR
) {
982 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
983 R200_BACK_SPECULAR_SOURCE_SHIFT
);
986 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
987 R200_BACK_SPECULAR_SOURCE_SHIFT
);
991 /* Default to SOURCE_MATERIAL:
994 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_EMISSIVE_SOURCE_SHIFT
) |
995 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_AMBIENT_SOURCE_SHIFT
) |
996 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_DIFFUSE_SOURCE_SHIFT
) |
997 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_SPECULAR_SOURCE_SHIFT
) |
998 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_EMISSIVE_SOURCE_SHIFT
) |
999 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_AMBIENT_SOURCE_SHIFT
) |
1000 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_DIFFUSE_SOURCE_SHIFT
) |
1001 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_SPECULAR_SOURCE_SHIFT
);
1004 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
]) {
1005 R200_STATECHANGE( rmesa
, tcl
);
1006 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
] = light_model_ctl1
;
1012 void r200UpdateMaterial( GLcontext
*ctx
)
1014 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1015 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
1016 GLfloat
*fcmd
= (GLfloat
*)R200_DB_STATE( mtl
[0] );
1017 GLfloat
*fcmd2
= (GLfloat
*)R200_DB_STATE( mtl
[1] );
1020 /* Might be possible and faster to update everything unconditionally? */
1021 if (ctx
->Light
.ColorMaterialEnabled
)
1022 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
1024 if (R200_DEBUG
& DEBUG_STATE
)
1025 fprintf(stderr
, "%s\n", __FUNCTION__
);
1027 if (mask
& MAT_BIT_FRONT_EMISSION
) {
1028 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
1029 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
1030 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
1031 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
1033 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
1034 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
1035 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
1036 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
1037 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
1039 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
1040 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
1041 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
1042 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
1043 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
1045 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
1046 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
1047 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
1048 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
1049 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
1051 if (mask
& MAT_BIT_FRONT_SHININESS
) {
1052 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
1055 if (mask
& MAT_BIT_BACK_EMISSION
) {
1056 fcmd2
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_BACK_EMISSION
][0];
1057 fcmd2
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_BACK_EMISSION
][1];
1058 fcmd2
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_BACK_EMISSION
][2];
1059 fcmd2
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_BACK_EMISSION
][3];
1061 if (mask
& MAT_BIT_BACK_AMBIENT
) {
1062 fcmd2
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][0];
1063 fcmd2
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][1];
1064 fcmd2
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][2];
1065 fcmd2
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][3];
1067 if (mask
& MAT_BIT_BACK_DIFFUSE
) {
1068 fcmd2
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][0];
1069 fcmd2
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][1];
1070 fcmd2
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][2];
1071 fcmd2
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][3];
1073 if (mask
& MAT_BIT_BACK_SPECULAR
) {
1074 fcmd2
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][0];
1075 fcmd2
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][1];
1076 fcmd2
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][2];
1077 fcmd2
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][3];
1079 if (mask
& MAT_BIT_BACK_SHININESS
) {
1080 fcmd2
[MTL_SHININESS
] = mat
[MAT_ATTRIB_BACK_SHININESS
][0];
1083 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
[0] );
1084 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
[1] );
1086 /* currently material changes cannot trigger a global ambient change, I believe this is correct
1087 update_global_ambient( ctx ); */
1092 * _MESA_NEW_NEED_EYE_COORDS
1094 * Uses derived state from mesa:
1099 * _ModelViewInvScale
1103 * which are calculated in light.c and are correct for the current
1104 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
1105 * and _MESA_NEW_NEED_EYE_COORDS.
1107 static void update_light( GLcontext
*ctx
)
1109 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1111 /* Have to check these, or have an automatic shortcircuit mechanism
1112 * to remove noop statechanges. (Or just do a better job on the
1116 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
];
1118 if (ctx
->_NeedEyeCoords
)
1119 tmp
&= ~R200_LIGHT_IN_MODELSPACE
;
1121 tmp
|= R200_LIGHT_IN_MODELSPACE
;
1123 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
])
1125 R200_STATECHANGE( rmesa
, tcl
);
1126 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] = tmp
;
1131 GLfloat
*fcmd
= (GLfloat
*)R200_DB_STATE( eye
);
1132 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1133 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1134 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1135 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1136 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1141 if (ctx
->Light
.Enabled
) {
1143 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1144 if (ctx
->Light
.Light
[p
].Enabled
) {
1145 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1146 GLfloat
*fcmd
= (GLfloat
*)R200_DB_STATE( lit
[p
] );
1148 if (l
->EyePosition
[3] == 0.0) {
1149 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1150 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1151 fcmd
[LIT_POSITION_W
] = 0;
1152 fcmd
[LIT_DIRECTION_W
] = 0;
1154 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1155 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1156 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1157 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1158 fcmd
[LIT_DIRECTION_W
] = 0;
1161 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1167 static void r200Lightfv( GLcontext
*ctx
, GLenum light
,
1168 GLenum pname
, const GLfloat
*params
)
1170 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1171 GLint p
= light
- GL_LIGHT0
;
1172 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1173 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1180 update_light_colors( ctx
, p
);
1183 case GL_SPOT_DIRECTION
:
1184 /* picked up in update_light */
1188 /* positions picked up in update_light, but can do flag here */
1189 GLuint flag
= (p
&1)? R200_LIGHT_1_IS_LOCAL
: R200_LIGHT_0_IS_LOCAL
;
1190 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1192 R200_STATECHANGE(rmesa
, tcl
);
1193 if (l
->EyePosition
[3] != 0.0F
)
1194 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1196 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1200 case GL_SPOT_EXPONENT
:
1201 R200_STATECHANGE(rmesa
, lit
[p
]);
1202 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1205 case GL_SPOT_CUTOFF
: {
1206 GLuint flag
= (p
&1) ? R200_LIGHT_1_IS_SPOT
: R200_LIGHT_0_IS_SPOT
;
1207 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1209 R200_STATECHANGE(rmesa
, lit
[p
]);
1210 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1212 R200_STATECHANGE(rmesa
, tcl
);
1213 if (l
->SpotCutoff
!= 180.0F
)
1214 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1216 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1221 case GL_CONSTANT_ATTENUATION
:
1222 R200_STATECHANGE(rmesa
, lit
[p
]);
1223 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1224 if ( params
[0] == 0.0 )
1225 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1227 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1229 case GL_LINEAR_ATTENUATION
:
1230 R200_STATECHANGE(rmesa
, lit
[p
]);
1231 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1233 case GL_QUADRATIC_ATTENUATION
:
1234 R200_STATECHANGE(rmesa
, lit
[p
]);
1235 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1241 /* Set RANGE_ATTEN only when needed */
1244 case GL_CONSTANT_ATTENUATION
:
1245 case GL_LINEAR_ATTENUATION
:
1246 case GL_QUADRATIC_ATTENUATION
: {
1247 GLuint
*icmd
= (GLuint
*)R200_DB_STATE( tcl
);
1248 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1249 GLuint atten_flag
= ( p
&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN
1250 : R200_LIGHT_0_ENABLE_RANGE_ATTEN
;
1251 GLuint atten_const_flag
= ( p
&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN
1252 : R200_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1254 if ( l
->EyePosition
[3] == 0.0F
||
1255 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1256 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1257 /* Disable attenuation */
1258 icmd
[idx
] &= ~atten_flag
;
1260 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1261 /* Enable only constant portion of attenuation calculation */
1262 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1264 /* Enable full attenuation calculation */
1265 icmd
[idx
] &= ~atten_const_flag
;
1266 icmd
[idx
] |= atten_flag
;
1270 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1281 static void r200LightModelfv( GLcontext
*ctx
, GLenum pname
,
1282 const GLfloat
*param
)
1284 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1287 case GL_LIGHT_MODEL_AMBIENT
:
1288 update_global_ambient( ctx
);
1291 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1292 R200_STATECHANGE( rmesa
, tcl
);
1293 if (ctx
->Light
.Model
.LocalViewer
)
1294 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LOCAL_VIEWER
;
1296 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_LOCAL_VIEWER
;
1299 case GL_LIGHT_MODEL_TWO_SIDE
:
1300 R200_STATECHANGE( rmesa
, tcl
);
1301 if (ctx
->Light
.Model
.TwoSide
)
1302 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LIGHT_TWOSIDE
;
1304 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~(R200_LIGHT_TWOSIDE
);
1305 if (rmesa
->TclFallback
) {
1306 r200ChooseRenderState( ctx
);
1307 r200ChooseVertexState( ctx
);
1311 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1312 r200UpdateSpecular(ctx
);
1320 static void r200ShadeModel( GLcontext
*ctx
, GLenum mode
)
1322 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1323 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1325 s
&= ~(R200_DIFFUSE_SHADE_MASK
|
1326 R200_ALPHA_SHADE_MASK
|
1327 R200_SPECULAR_SHADE_MASK
|
1328 R200_FOG_SHADE_MASK
);
1332 s
|= (R200_DIFFUSE_SHADE_FLAT
|
1333 R200_ALPHA_SHADE_FLAT
|
1334 R200_SPECULAR_SHADE_FLAT
|
1335 R200_FOG_SHADE_FLAT
);
1338 s
|= (R200_DIFFUSE_SHADE_GOURAUD
|
1339 R200_ALPHA_SHADE_GOURAUD
|
1340 R200_SPECULAR_SHADE_GOURAUD
|
1341 R200_FOG_SHADE_GOURAUD
);
1347 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1348 R200_STATECHANGE( rmesa
, set
);
1349 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1354 /* =============================================================
1358 static void r200ClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1360 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1361 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1362 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1364 R200_STATECHANGE( rmesa
, ucp
[p
] );
1365 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1366 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1367 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1368 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1371 static void r200UpdateClipPlanes( GLcontext
*ctx
)
1373 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1376 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1377 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1378 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1380 R200_STATECHANGE( rmesa
, ucp
[p
] );
1381 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1382 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1383 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1384 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1390 /* =============================================================
1394 static void r200StencilFunc( GLcontext
*ctx
, GLenum func
,
1395 GLint ref
, GLuint mask
)
1397 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1398 GLuint refmask
= ((ctx
->Stencil
.Ref
[0] << R200_STENCIL_REF_SHIFT
) |
1399 (ctx
->Stencil
.ValueMask
[0] << R200_STENCIL_MASK_SHIFT
));
1401 R200_STATECHANGE( rmesa
, ctx
);
1402 R200_STATECHANGE( rmesa
, msk
);
1404 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~R200_STENCIL_TEST_MASK
;
1405 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(R200_STENCIL_REF_MASK
|
1406 R200_STENCIL_VALUE_MASK
);
1408 switch ( ctx
->Stencil
.Function
[0] ) {
1410 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_NEVER
;
1413 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_LESS
;
1416 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_EQUAL
;
1419 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_LEQUAL
;
1422 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_GREATER
;
1425 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_NEQUAL
;
1428 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_GEQUAL
;
1431 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_ALWAYS
;
1435 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1438 static void r200StencilMask( GLcontext
*ctx
, GLuint mask
)
1440 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1442 R200_STATECHANGE( rmesa
, msk
);
1443 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~R200_STENCIL_WRITE_MASK
;
1444 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1445 (ctx
->Stencil
.WriteMask
[0] << R200_STENCIL_WRITEMASK_SHIFT
);
1448 static void r200StencilOp( GLcontext
*ctx
, GLenum fail
,
1449 GLenum zfail
, GLenum zpass
)
1451 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1453 R200_STATECHANGE( rmesa
, ctx
);
1454 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(R200_STENCIL_FAIL_MASK
|
1455 R200_STENCIL_ZFAIL_MASK
|
1456 R200_STENCIL_ZPASS_MASK
);
1458 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1460 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_KEEP
;
1463 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_ZERO
;
1466 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_REPLACE
;
1469 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_INC
;
1472 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_DEC
;
1474 case GL_INCR_WRAP_EXT
:
1475 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_INC_WRAP
;
1477 case GL_DECR_WRAP_EXT
:
1478 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_DEC_WRAP
;
1481 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_INVERT
;
1485 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1487 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_KEEP
;
1490 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_ZERO
;
1493 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_REPLACE
;
1496 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_INC
;
1499 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_DEC
;
1501 case GL_INCR_WRAP_EXT
:
1502 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_INC_WRAP
;
1504 case GL_DECR_WRAP_EXT
:
1505 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_DEC_WRAP
;
1508 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_INVERT
;
1512 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1514 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_KEEP
;
1517 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_ZERO
;
1520 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_REPLACE
;
1523 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_INC
;
1526 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_DEC
;
1528 case GL_INCR_WRAP_EXT
:
1529 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_INC_WRAP
;
1531 case GL_DECR_WRAP_EXT
:
1532 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_DEC_WRAP
;
1535 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_INVERT
;
1540 static void r200ClearStencil( GLcontext
*ctx
, GLint s
)
1542 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1544 rmesa
->state
.stencil
.clear
=
1545 ((GLuint
) ctx
->Stencil
.Clear
|
1546 (0xff << R200_STENCIL_MASK_SHIFT
) |
1547 (ctx
->Stencil
.WriteMask
[0] << R200_STENCIL_WRITEMASK_SHIFT
));
1551 /* =============================================================
1552 * Window position and viewport transformation
1556 * To correctly position primitives:
1558 #define SUBPIXEL_X 0.125
1559 #define SUBPIXEL_Y 0.125
1561 void r200UpdateWindow( GLcontext
*ctx
)
1563 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1564 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1565 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1566 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1567 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1569 GLfloat sx
= v
[MAT_SX
];
1570 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1571 GLfloat sy
= - v
[MAT_SY
];
1572 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1573 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1574 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1576 R200_FIREVERTICES( rmesa
);
1577 R200_STATECHANGE( rmesa
, vpt
);
1579 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = *(GLuint
*)&sx
;
1580 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1581 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = *(GLuint
*)&sy
;
1582 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1583 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = *(GLuint
*)&sz
;
1584 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = *(GLuint
*)&tz
;
1589 static void r200Viewport( GLcontext
*ctx
, GLint x
, GLint y
,
1590 GLsizei width
, GLsizei height
)
1592 /* Don't pipeline viewport changes, conflict with window offset
1593 * setting below. Could apply deltas to rescue pipelined viewport
1594 * values, or keep the originals hanging around.
1596 R200_FIREVERTICES( R200_CONTEXT(ctx
) );
1597 r200UpdateWindow( ctx
);
1600 static void r200DepthRange( GLcontext
*ctx
, GLclampd nearval
,
1603 r200UpdateWindow( ctx
);
1606 void r200UpdateViewportOffset( GLcontext
*ctx
)
1608 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1609 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1610 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1611 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1612 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1614 GLfloat tx
= v
[MAT_TX
] + xoffset
;
1615 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
;
1617 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != *(GLuint
*)&tx
||
1618 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != *(GLuint
*)&ty
)
1620 /* Note: this should also modify whatever data the context reset
1623 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1624 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1626 /* update polygon stipple x/y screen offset */
1629 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1631 m
&= ~(R200_STIPPLE_X_OFFSET_MASK
|
1632 R200_STIPPLE_Y_OFFSET_MASK
);
1634 /* add magic offsets, then invert */
1635 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & R200_STIPPLE_COORD_MASK
);
1636 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1637 & R200_STIPPLE_COORD_MASK
);
1639 m
|= ((stx
<< R200_STIPPLE_X_OFFSET_SHIFT
) |
1640 (sty
<< R200_STIPPLE_Y_OFFSET_SHIFT
));
1642 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1643 R200_STATECHANGE( rmesa
, msc
);
1644 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1649 r200UpdateScissor( ctx
);
1654 /* =============================================================
1658 static void r200ClearColor( GLcontext
*ctx
, const GLfloat c
[4] )
1660 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1662 CLAMPED_FLOAT_TO_UBYTE(color
[0], c
[0]);
1663 CLAMPED_FLOAT_TO_UBYTE(color
[1], c
[1]);
1664 CLAMPED_FLOAT_TO_UBYTE(color
[2], c
[2]);
1665 CLAMPED_FLOAT_TO_UBYTE(color
[3], c
[3]);
1666 rmesa
->state
.color
.clear
= r200PackColor( rmesa
->r200Screen
->cpp
,
1668 color
[2], color
[3] );
1672 static void r200RenderMode( GLcontext
*ctx
, GLenum mode
)
1674 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1675 FALLBACK( rmesa
, R200_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1679 static GLuint r200_rop_tab
[] = {
1682 R200_ROP_AND_REVERSE
,
1684 R200_ROP_AND_INVERTED
,
1691 R200_ROP_OR_REVERSE
,
1692 R200_ROP_COPY_INVERTED
,
1693 R200_ROP_OR_INVERTED
,
1698 static void r200LogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1700 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1701 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1705 R200_STATECHANGE( rmesa
, msk
);
1706 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = r200_rop_tab
[rop
];
1710 void r200SetCliprects( r200ContextPtr rmesa
, GLenum mode
)
1712 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1716 rmesa
->numClipRects
= dPriv
->numClipRects
;
1717 rmesa
->pClipRects
= dPriv
->pClipRects
;
1720 /* Can't ignore 2d windows if we are page flipping.
1722 if ( dPriv
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1723 rmesa
->numClipRects
= dPriv
->numClipRects
;
1724 rmesa
->pClipRects
= dPriv
->pClipRects
;
1727 rmesa
->numClipRects
= dPriv
->numBackClipRects
;
1728 rmesa
->pClipRects
= dPriv
->pBackClipRects
;
1732 fprintf(stderr
, "bad mode in r200SetCliprects\n");
1736 if (rmesa
->state
.scissor
.enabled
)
1737 r200RecalcScissorRects( rmesa
);
1741 static void r200DrawBuffer( GLcontext
*ctx
, GLenum mode
)
1743 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1745 if (R200_DEBUG
& DEBUG_DRI
)
1746 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1747 _mesa_lookup_enum_by_nr( mode
));
1749 R200_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1752 * _DrawDestMask is easier to cope with than <mode>.
1754 switch ( ctx
->Color
._DrawDestMask
[0] ) {
1755 case DD_FRONT_LEFT_BIT
:
1756 FALLBACK( rmesa
, R200_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1757 r200SetCliprects( rmesa
, GL_FRONT_LEFT
);
1759 case DD_BACK_LEFT_BIT
:
1760 FALLBACK( rmesa
, R200_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1761 r200SetCliprects( rmesa
, GL_BACK_LEFT
);
1764 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
1765 FALLBACK( rmesa
, R200_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1769 /* We want to update the s/w rast state too so that r200SetBuffer()
1772 _swrast_DrawBuffer(ctx
, mode
);
1774 R200_STATECHANGE( rmesa
, ctx
);
1775 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
] = ((rmesa
->state
.color
.drawOffset
+
1776 rmesa
->r200Screen
->fbLocation
)
1777 & R200_COLOROFFSET_MASK
);
1778 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = rmesa
->state
.color
.drawPitch
;
1782 static void r200ReadBuffer( GLcontext
*ctx
, GLenum mode
)
1784 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1787 /* =============================================================
1788 * State enable/disable
1791 static void r200Enable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1793 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1796 if ( R200_DEBUG
& DEBUG_STATE
)
1797 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1798 _mesa_lookup_enum_by_nr( cap
),
1799 state
? "GL_TRUE" : "GL_FALSE" );
1802 /* Fast track this one...
1810 R200_STATECHANGE( rmesa
, ctx
);
1812 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_ALPHA_TEST_ENABLE
;
1814 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_ALPHA_TEST_ENABLE
;
1819 case GL_COLOR_LOGIC_OP
:
1820 r200_set_blend_state( ctx
);
1823 case GL_CLIP_PLANE0
:
1824 case GL_CLIP_PLANE1
:
1825 case GL_CLIP_PLANE2
:
1826 case GL_CLIP_PLANE3
:
1827 case GL_CLIP_PLANE4
:
1828 case GL_CLIP_PLANE5
:
1829 p
= cap
-GL_CLIP_PLANE0
;
1830 R200_STATECHANGE( rmesa
, tcl
);
1832 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (R200_UCP_ENABLE_0
<<p
);
1833 r200ClipPlane( ctx
, cap
, NULL
);
1836 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(R200_UCP_ENABLE_0
<<p
);
1840 case GL_COLOR_MATERIAL
:
1841 r200ColorMaterial( ctx
, 0, 0 );
1842 r200UpdateMaterial( ctx
);
1846 r200CullFace( ctx
, 0 );
1850 R200_STATECHANGE(rmesa
, ctx
);
1852 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_Z_ENABLE
;
1854 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_Z_ENABLE
;
1859 R200_STATECHANGE(rmesa
, ctx
);
1861 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_DITHER_ENABLE
;
1862 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1864 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_DITHER_ENABLE
;
1865 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1870 R200_STATECHANGE(rmesa
, ctx
);
1872 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_FOG_ENABLE
;
1873 r200Fogfv( ctx
, GL_FOG_MODE
, 0 );
1875 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_FOG_ENABLE
;
1876 R200_STATECHANGE(rmesa
, tcl
);
1877 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~R200_TCL_FOG_MASK
;
1879 r200UpdateSpecular( ctx
); /* for PK_SPEC */
1880 if (rmesa
->TclFallback
)
1881 r200ChooseVertexState( ctx
);
1882 _mesa_allow_light_in_model( ctx
, !state
);
1893 R200_STATECHANGE(rmesa
, tcl
);
1894 p
= cap
- GL_LIGHT0
;
1896 flag
= (R200_LIGHT_1_ENABLE
|
1897 R200_LIGHT_1_ENABLE_AMBIENT
|
1898 R200_LIGHT_1_ENABLE_SPECULAR
);
1900 flag
= (R200_LIGHT_0_ENABLE
|
1901 R200_LIGHT_0_ENABLE_AMBIENT
|
1902 R200_LIGHT_0_ENABLE_SPECULAR
);
1905 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1907 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1911 update_light_colors( ctx
, p
);
1915 r200UpdateSpecular(ctx
);
1918 case GL_LINE_SMOOTH
:
1919 R200_STATECHANGE( rmesa
, ctx
);
1921 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_ANTI_ALIAS_LINE
;
1923 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_ANTI_ALIAS_LINE
;
1927 case GL_LINE_STIPPLE
:
1928 R200_STATECHANGE( rmesa
, set
);
1930 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] |= R200_PATTERN_ENABLE
;
1932 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] &= ~R200_PATTERN_ENABLE
;
1937 R200_STATECHANGE( rmesa
, tcl
);
1939 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_NORMALIZE_NORMALS
;
1941 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_NORMALIZE_NORMALS
;
1945 /* Pointsize registers on r200 don't seem to do anything. Maybe
1946 * have to pass pointsizes as vertex parameters? In any case,
1947 * setting pointmin == pointsizemax == 1.0, and doing nothing
1948 * for aa is enough to satisfy conform.
1950 case GL_POINT_SMOOTH
:
1953 /* These don't really do anything, as we don't use the 3vtx
1957 case GL_POLYGON_OFFSET_POINT
:
1958 R200_STATECHANGE( rmesa
, set
);
1960 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_ZBIAS_ENABLE_POINT
;
1962 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_ZBIAS_ENABLE_POINT
;
1966 case GL_POLYGON_OFFSET_LINE
:
1967 R200_STATECHANGE( rmesa
, set
);
1969 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_ZBIAS_ENABLE_LINE
;
1971 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_ZBIAS_ENABLE_LINE
;
1976 case GL_POLYGON_OFFSET_FILL
:
1977 R200_STATECHANGE( rmesa
, set
);
1979 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_ZBIAS_ENABLE_TRI
;
1981 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_ZBIAS_ENABLE_TRI
;
1985 case GL_POLYGON_SMOOTH
:
1986 R200_STATECHANGE( rmesa
, ctx
);
1988 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_ANTI_ALIAS_POLY
;
1990 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_ANTI_ALIAS_POLY
;
1994 case GL_POLYGON_STIPPLE
:
1995 R200_STATECHANGE(rmesa
, set
);
1997 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] |= R200_STIPPLE_ENABLE
;
1999 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] &= ~R200_STIPPLE_ENABLE
;
2003 case GL_RESCALE_NORMAL_EXT
: {
2004 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
2005 R200_STATECHANGE( rmesa
, tcl
);
2007 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_RESCALE_NORMALS
;
2009 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_RESCALE_NORMALS
;
2014 case GL_SCISSOR_TEST
:
2015 R200_FIREVERTICES( rmesa
);
2016 rmesa
->state
.scissor
.enabled
= state
;
2017 r200UpdateScissor( ctx
);
2020 case GL_STENCIL_TEST
:
2021 if ( rmesa
->state
.stencil
.hwBuffer
) {
2022 R200_STATECHANGE( rmesa
, ctx
);
2024 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_STENCIL_ENABLE
;
2026 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_STENCIL_ENABLE
;
2029 FALLBACK( rmesa
, R200_FALLBACK_STENCIL
, state
);
2033 case GL_TEXTURE_GEN_Q
:
2034 case GL_TEXTURE_GEN_R
:
2035 case GL_TEXTURE_GEN_S
:
2036 case GL_TEXTURE_GEN_T
:
2037 /* Picked up in r200UpdateTextureState.
2039 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
2042 case GL_COLOR_SUM_EXT
:
2043 r200UpdateSpecular ( ctx
);
2046 case GL_VERTEX_PROGRAM_ARB
:
2047 TCL_FALLBACK(rmesa
->glCtx
, R200_TCL_FALLBACK_TCL_DISABLE
, state
);
2056 void r200LightingSpaceChange( GLcontext
*ctx
)
2058 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
2061 if (R200_DEBUG
& DEBUG_STATE
)
2062 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2063 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
]);
2065 if (ctx
->_NeedEyeCoords
)
2066 tmp
= ctx
->Transform
.RescaleNormals
;
2068 tmp
= !ctx
->Transform
.RescaleNormals
;
2070 R200_STATECHANGE( rmesa
, tcl
);
2072 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_RESCALE_NORMALS
;
2074 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_RESCALE_NORMALS
;
2077 if (R200_DEBUG
& DEBUG_STATE
)
2078 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2079 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
]);
2082 /* =============================================================
2083 * Deferred state management - matrices, textures, other?
2089 static void upload_matrix( r200ContextPtr rmesa
, GLfloat
*src
, int idx
)
2091 float *dest
= ((float *)R200_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2095 for (i
= 0 ; i
< 4 ; i
++) {
2099 *dest
++ = src
[i
+12];
2102 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2105 static void upload_matrix_t( r200ContextPtr rmesa
, const GLfloat
*src
, int idx
)
2107 float *dest
= ((float *)R200_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2108 memcpy(dest
, src
, 16*sizeof(float));
2109 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2113 static void update_texturematrix( GLcontext
*ctx
)
2115 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
2116 GLuint tpc
= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_0
];
2117 GLuint compsel
= rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
];
2120 if (R200_DEBUG
& DEBUG_STATE
)
2121 fprintf(stderr
, "%s before COMPSEL: %x\n", __FUNCTION__
,
2122 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
]);
2124 rmesa
->TexMatEnabled
= 0;
2125 rmesa
->TexMatCompSel
= 0;
2127 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
2128 if (!ctx
->Texture
.Unit
[unit
]._ReallyEnabled
)
2131 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2132 rmesa
->TexMatEnabled
|= (R200_TEXGEN_TEXMAT_0_ENABLE
|
2133 R200_TEXMAT_0_ENABLE
) << unit
;
2135 rmesa
->TexMatCompSel
|= R200_OUTPUT_TEX_0
<< unit
;
2137 if (rmesa
->TexGenEnabled
& (R200_TEXMAT_0_ENABLE
<< unit
)) {
2138 /* Need to preconcatenate any active texgen
2139 * obj/eyeplane matrices:
2141 _math_matrix_mul_matrix( &rmesa
->tmpmat
,
2142 ctx
->TextureMatrixStack
[unit
].Top
,
2143 &rmesa
->TexGenMatrix
[unit
] );
2144 upload_matrix( rmesa
, rmesa
->tmpmat
.m
, R200_MTX_TEX0
+unit
);
2147 upload_matrix( rmesa
, ctx
->TextureMatrixStack
[unit
].Top
->m
,
2148 R200_MTX_TEX0
+unit
);
2151 else if (rmesa
->TexGenEnabled
& (R200_TEXMAT_0_ENABLE
<< unit
)) {
2152 upload_matrix( rmesa
, rmesa
->TexGenMatrix
[unit
].m
,
2153 R200_MTX_TEX0
+unit
);
2157 tpc
= (rmesa
->TexMatEnabled
| rmesa
->TexGenEnabled
);
2158 if (tpc
!= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_0
]) {
2159 R200_STATECHANGE(rmesa
, tcg
);
2160 rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_0
] = tpc
;
2163 compsel
&= ~R200_OUTPUT_TEX_MASK
;
2164 compsel
|= rmesa
->TexMatCompSel
| rmesa
->TexGenCompSel
;
2165 if (compsel
!= rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
]) {
2166 R200_STATECHANGE(rmesa
, vtx
);
2167 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] = compsel
;
2173 void r200ValidateState( GLcontext
*ctx
)
2175 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
2176 GLuint new_state
= rmesa
->NewGLState
;
2178 if (new_state
& _NEW_TEXTURE
) {
2179 r200UpdateTextureState( ctx
);
2180 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2183 /* Need an event driven matrix update?
2185 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2186 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, R200_MTX_MVP
);
2188 /* Need these for lighting (shouldn't upload otherwise)
2190 if (new_state
& (_NEW_MODELVIEW
)) {
2191 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, R200_MTX_MV
);
2192 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, R200_MTX_IMV
);
2195 /* Does this need to be triggered on eg. modelview for
2196 * texgen-derived objplane/eyeplane matrices?
2198 if (new_state
& (_NEW_TEXTURE
|_NEW_TEXTURE_MATRIX
)) {
2199 update_texturematrix( ctx
);
2202 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2203 update_light( ctx
);
2206 /* emit all active clip planes if projection matrix changes.
2208 if (new_state
& (_NEW_PROJECTION
)) {
2209 if (ctx
->Transform
.ClipPlanesEnabled
)
2210 r200UpdateClipPlanes( ctx
);
2214 rmesa
->NewGLState
= 0;
2218 static void r200InvalidateState( GLcontext
*ctx
, GLuint new_state
)
2220 _swrast_InvalidateState( ctx
, new_state
);
2221 _swsetup_InvalidateState( ctx
, new_state
);
2222 _ac_InvalidateState( ctx
, new_state
);
2223 _tnl_InvalidateState( ctx
, new_state
);
2224 _ae_invalidate_state( ctx
, new_state
);
2225 R200_CONTEXT(ctx
)->NewGLState
|= new_state
;
2226 r200VtxfmtInvalidate( ctx
);
2229 /* A hack. The r200 can actually cope just fine with materials
2230 * between begin/ends, so fix this. But how ?
2232 static GLboolean
check_material( GLcontext
*ctx
)
2234 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2237 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2238 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2240 if (tnl
->vb
.AttribPtr
[i
] &&
2241 tnl
->vb
.AttribPtr
[i
]->stride
)
2247 static void r200WrapRunPipeline( GLcontext
*ctx
)
2249 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
2250 GLboolean has_material
;
2253 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2257 if (rmesa
->NewGLState
)
2258 r200ValidateState( ctx
);
2260 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2263 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2266 /* Run the pipeline.
2268 _tnl_run_pipeline( ctx
);
2271 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2276 /* Initialize the driver's state functions.
2278 void r200InitStateFuncs( struct dd_function_table
*functions
)
2280 functions
->UpdateState
= r200InvalidateState
;
2281 functions
->LightingSpaceChange
= r200LightingSpaceChange
;
2283 functions
->DrawBuffer
= r200DrawBuffer
;
2284 functions
->ReadBuffer
= r200ReadBuffer
;
2286 functions
->AlphaFunc
= r200AlphaFunc
;
2287 functions
->BlendColor
= r200BlendColor
;
2288 functions
->BlendEquationSeparate
= r200BlendEquationSeparate
;
2289 functions
->BlendFuncSeparate
= r200BlendFuncSeparate
;
2290 functions
->ClearColor
= r200ClearColor
;
2291 functions
->ClearDepth
= NULL
;
2292 functions
->ClearIndex
= NULL
;
2293 functions
->ClearStencil
= r200ClearStencil
;
2294 functions
->ClipPlane
= r200ClipPlane
;
2295 functions
->ColorMask
= r200ColorMask
;
2296 functions
->CullFace
= r200CullFace
;
2297 functions
->DepthFunc
= r200DepthFunc
;
2298 functions
->DepthMask
= r200DepthMask
;
2299 functions
->DepthRange
= r200DepthRange
;
2300 functions
->Enable
= r200Enable
;
2301 functions
->Fogfv
= r200Fogfv
;
2302 functions
->FrontFace
= r200FrontFace
;
2303 functions
->Hint
= NULL
;
2304 functions
->IndexMask
= NULL
;
2305 functions
->LightModelfv
= r200LightModelfv
;
2306 functions
->Lightfv
= r200Lightfv
;
2307 functions
->LineStipple
= r200LineStipple
;
2308 functions
->LineWidth
= r200LineWidth
;
2309 functions
->LogicOpcode
= r200LogicOpCode
;
2310 functions
->PolygonMode
= r200PolygonMode
;
2311 functions
->PolygonOffset
= r200PolygonOffset
;
2312 functions
->PolygonStipple
= r200PolygonStipple
;
2313 functions
->PointSize
= r200PointSize
;
2314 functions
->RenderMode
= r200RenderMode
;
2315 functions
->Scissor
= r200Scissor
;
2316 functions
->ShadeModel
= r200ShadeModel
;
2317 functions
->StencilFunc
= r200StencilFunc
;
2318 functions
->StencilMask
= r200StencilMask
;
2319 functions
->StencilOp
= r200StencilOp
;
2320 functions
->Viewport
= r200Viewport
;
2322 /* Swrast hooks for imaging extensions:
2324 functions
->CopyColorTable
= _swrast_CopyColorTable
;
2325 functions
->CopyColorSubTable
= _swrast_CopyColorSubTable
;
2326 functions
->CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
2327 functions
->CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
2331 void r200InitTnlFuncs( GLcontext
*ctx
)
2333 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= r200UpdateMaterial
;
2334 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= r200WrapRunPipeline
;