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
;
108 * Calculate the hardware blend factor setting. This same function is used
109 * for source and destination of both alpha and RGB.
112 * The hardware register value for the specified blend factor. This value
113 * will need to be shifted into the correct position for either source or
114 * destination factor.
117 * Since the two cases where source and destination are handled differently
118 * are essentially error cases, they should never happen. Determine if these
119 * cases can be removed.
121 static int blend_factor( GLenum factor
, GLboolean is_src
)
127 func
= R200_BLEND_GL_ZERO
;
130 func
= R200_BLEND_GL_ONE
;
133 func
= R200_BLEND_GL_DST_COLOR
;
135 case GL_ONE_MINUS_DST_COLOR
:
136 func
= R200_BLEND_GL_ONE_MINUS_DST_COLOR
;
139 func
= R200_BLEND_GL_SRC_COLOR
;
141 case GL_ONE_MINUS_SRC_COLOR
:
142 func
= R200_BLEND_GL_ONE_MINUS_SRC_COLOR
;
145 func
= R200_BLEND_GL_SRC_ALPHA
;
147 case GL_ONE_MINUS_SRC_ALPHA
:
148 func
= R200_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
151 func
= R200_BLEND_GL_DST_ALPHA
;
153 case GL_ONE_MINUS_DST_ALPHA
:
154 func
= R200_BLEND_GL_ONE_MINUS_DST_ALPHA
;
156 case GL_SRC_ALPHA_SATURATE
:
157 func
= (is_src
) ? R200_BLEND_GL_SRC_ALPHA_SATURATE
: R200_BLEND_GL_ZERO
;
159 case GL_CONSTANT_COLOR
:
160 func
= R200_BLEND_GL_CONST_COLOR
;
162 case GL_ONE_MINUS_CONSTANT_COLOR
:
163 func
= R200_BLEND_GL_ONE_MINUS_CONST_COLOR
;
165 case GL_CONSTANT_ALPHA
:
166 func
= R200_BLEND_GL_CONST_ALPHA
;
168 case GL_ONE_MINUS_CONSTANT_ALPHA
:
169 func
= R200_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
172 func
= (is_src
) ? R200_BLEND_GL_ONE
: R200_BLEND_GL_ZERO
;
178 * Sets both the blend equation and the blend function.
179 * This is done in a single
180 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
181 * change the interpretation of the blend function.
182 * Also, make sure that blend function and blend equation are set to their default
183 * value if color blending is not enabled, since at least blend equations GL_MIN
184 * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
187 static void r200_set_blend_state( GLcontext
* ctx
)
189 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
190 GLuint cntl
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &
191 ~(R200_ROP_ENABLE
| R200_ALPHA_BLEND_ENABLE
);
193 int func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
194 (R200_BLEND_GL_ZERO
<< R200_DST_BLEND_SHIFT
);
195 int eqn
= R200_COMB_FCN_ADD_CLAMP
;
197 R200_STATECHANGE( rmesa
, ctx
);
199 if (ctx
->Color
._LogicOpEnabled
) {
200 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
| R200_ROP_ENABLE
;
201 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = eqn
| func
;
203 } else if (ctx
->Color
.BlendEnabled
) {
204 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
| R200_ALPHA_BLEND_ENABLE
;
207 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = cntl
;
208 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = eqn
| func
;
212 func
= (blend_factor( ctx
->Color
.BlendSrcRGB
, GL_TRUE
) << R200_SRC_BLEND_SHIFT
) |
213 (blend_factor( ctx
->Color
.BlendDstRGB
, GL_FALSE
) << R200_DST_BLEND_SHIFT
);
215 switch(ctx
->Color
.BlendEquationRGB
) {
218 eqn
= R200_COMB_FCN_ADD_CLAMP
;
221 case GL_FUNC_SUBTRACT
:
222 eqn
= R200_COMB_FCN_SUB_CLAMP
;
225 case GL_FUNC_REVERSE_SUBTRACT
:
226 eqn
= R200_COMB_FCN_RSUB_CLAMP
;
230 eqn
= R200_COMB_FCN_MIN
;
231 func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
232 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
236 eqn
= R200_COMB_FCN_MAX
;
237 func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
238 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
242 fprintf( stderr
, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
243 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
247 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = eqn
| func
;
250 static void r200BlendEquationSeparate( GLcontext
*ctx
,
251 GLenum modeRGB
, GLenum modeA
)
253 r200_set_blend_state( ctx
);
256 static void r200BlendFuncSeparate( GLcontext
*ctx
,
257 GLenum sfactorRGB
, GLenum dfactorRGB
,
258 GLenum sfactorA
, GLenum dfactorA
)
260 r200_set_blend_state( ctx
);
264 /* =============================================================
268 static void r200DepthFunc( GLcontext
*ctx
, GLenum func
)
270 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
272 R200_STATECHANGE( rmesa
, ctx
);
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~R200_Z_TEST_MASK
;
275 switch ( ctx
->Depth
.Func
) {
277 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_NEVER
;
280 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_LESS
;
283 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_EQUAL
;
286 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_LEQUAL
;
289 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_GREATER
;
292 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_NEQUAL
;
295 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_GEQUAL
;
298 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_ALWAYS
;
304 static void r200DepthMask( GLcontext
*ctx
, GLboolean flag
)
306 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
307 R200_STATECHANGE( rmesa
, ctx
);
309 if ( ctx
->Depth
.Mask
) {
310 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_WRITE_ENABLE
;
312 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~R200_Z_WRITE_ENABLE
;
317 /* =============================================================
322 static void r200Fogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
324 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
325 union { int i
; float f
; } c
, d
;
329 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
330 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
334 if (!ctx
->Fog
.Enabled
)
336 R200_STATECHANGE(rmesa
, tcl
);
337 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~R200_TCL_FOG_MASK
;
338 switch (ctx
->Fog
.Mode
) {
340 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_TCL_FOG_LINEAR
;
341 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
346 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
347 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
351 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_TCL_FOG_EXP
;
353 d
.f
= -ctx
->Fog
.Density
;
356 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_TCL_FOG_EXP2
;
358 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
365 switch (ctx
->Fog
.Mode
) {
368 d
.f
= -ctx
->Fog
.Density
;
372 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
380 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
381 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
385 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
386 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
391 R200_STATECHANGE( rmesa
, ctx
);
392 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
393 i
= r200PackColor( 4, col
[0], col
[1], col
[2], 0 );
394 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~R200_FOG_COLOR_MASK
;
395 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |= i
;
397 case GL_FOG_COORDINATE_SOURCE_EXT
:
405 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
406 R200_STATECHANGE( rmesa
, fog
);
407 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
408 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
413 /* =============================================================
418 static GLboolean
intersect_rect( drm_clip_rect_t
*out
,
423 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
424 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
425 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
426 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
427 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
428 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
433 void r200RecalcScissorRects( r200ContextPtr rmesa
)
435 drm_clip_rect_t
*out
;
438 /* Grow cliprect store?
440 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
441 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
442 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
443 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
446 if (rmesa
->state
.scissor
.pClipRects
)
447 FREE(rmesa
->state
.scissor
.pClipRects
);
449 rmesa
->state
.scissor
.pClipRects
=
450 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
451 sizeof(drm_clip_rect_t
) );
453 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
454 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
459 out
= rmesa
->state
.scissor
.pClipRects
;
460 rmesa
->state
.scissor
.numClipRects
= 0;
462 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
463 if ( intersect_rect( out
,
464 &rmesa
->pClipRects
[i
],
465 &rmesa
->state
.scissor
.rect
) ) {
466 rmesa
->state
.scissor
.numClipRects
++;
473 static void r200UpdateScissor( GLcontext
*ctx
)
475 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
477 if ( rmesa
->dri
.drawable
) {
478 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
480 int x
= ctx
->Scissor
.X
;
481 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
482 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
483 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
485 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
486 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
487 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
488 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
490 r200RecalcScissorRects( rmesa
);
495 static void r200Scissor( GLcontext
*ctx
,
496 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
498 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
500 if ( ctx
->Scissor
.Enabled
) {
501 R200_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
502 r200UpdateScissor( ctx
);
508 /* =============================================================
512 static void r200CullFace( GLcontext
*ctx
, GLenum unused
)
514 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
515 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
516 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
518 s
|= R200_FFACE_SOLID
| R200_BFACE_SOLID
;
519 t
&= ~(R200_CULL_FRONT
| R200_CULL_BACK
);
521 if ( ctx
->Polygon
.CullFlag
) {
522 switch ( ctx
->Polygon
.CullFaceMode
) {
524 s
&= ~R200_FFACE_SOLID
;
525 t
|= R200_CULL_FRONT
;
528 s
&= ~R200_BFACE_SOLID
;
531 case GL_FRONT_AND_BACK
:
532 s
&= ~(R200_FFACE_SOLID
| R200_BFACE_SOLID
);
533 t
|= (R200_CULL_FRONT
| R200_CULL_BACK
);
538 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
539 R200_STATECHANGE(rmesa
, set
);
540 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
543 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
544 R200_STATECHANGE(rmesa
, tcl
);
545 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
549 static void r200FrontFace( GLcontext
*ctx
, GLenum mode
)
551 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
553 R200_STATECHANGE( rmesa
, set
);
554 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_FFACE_CULL_DIR_MASK
;
556 R200_STATECHANGE( rmesa
, tcl
);
557 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~R200_CULL_FRONT_IS_CCW
;
561 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_FFACE_CULL_CW
;
564 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_FFACE_CULL_CCW
;
565 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_CULL_FRONT_IS_CCW
;
570 /* =============================================================
573 static void r200PointSize( GLcontext
*ctx
, GLfloat size
)
575 if (0) fprintf(stderr
, "%s: %f\n", __FUNCTION__
, size
);
578 /* =============================================================
581 static void r200LineWidth( GLcontext
*ctx
, GLfloat widthf
)
583 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
585 R200_STATECHANGE( rmesa
, lin
);
586 R200_STATECHANGE( rmesa
, set
);
588 /* Line width is stored in U6.4 format.
590 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] &= ~0xffff;
591 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] |= (GLuint
)(ctx
->Line
._Width
* 16.0);
593 if ( widthf
> 1.0 ) {
594 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_WIDELINE_ENABLE
;
596 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_WIDELINE_ENABLE
;
600 static void r200LineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
602 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
604 R200_STATECHANGE( rmesa
, lin
);
605 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
606 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
610 /* =============================================================
613 static void r200ColorMask( GLcontext
*ctx
,
614 GLboolean r
, GLboolean g
,
615 GLboolean b
, GLboolean a
)
617 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
618 GLuint mask
= r200PackColor( rmesa
->r200Screen
->cpp
,
619 ctx
->Color
.ColorMask
[RCOMP
],
620 ctx
->Color
.ColorMask
[GCOMP
],
621 ctx
->Color
.ColorMask
[BCOMP
],
622 ctx
->Color
.ColorMask
[ACOMP
] );
624 GLuint flag
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] & ~R200_PLANE_MASK_ENABLE
;
626 if (!(r
&& g
&& b
&& a
))
627 flag
|= R200_PLANE_MASK_ENABLE
;
629 if ( rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] != flag
) {
630 R200_STATECHANGE( rmesa
, ctx
);
631 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = flag
;
634 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
635 R200_STATECHANGE( rmesa
, msk
);
636 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
641 /* =============================================================
645 static void r200PolygonOffset( GLcontext
*ctx
,
646 GLfloat factor
, GLfloat units
)
648 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
649 GLfloat constant
= units
* rmesa
->state
.depth
.scale
;
654 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
656 R200_STATECHANGE( rmesa
, zbs
);
657 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = *(GLuint
*)&factor
;
658 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = *(GLuint
*)&constant
;
661 static void r200PolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
663 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
665 drm_radeon_stipple_t stipple
;
667 /* Must flip pattern upside down.
669 for ( i
= 0 ; i
< 32 ; i
++ ) {
670 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
673 /* TODO: push this into cmd mechanism
675 R200_FIREVERTICES( rmesa
);
676 LOCK_HARDWARE( rmesa
);
678 /* FIXME: Use window x,y offsets into stipple RAM.
680 stipple
.mask
= rmesa
->state
.stipple
.mask
;
681 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
682 &stipple
, sizeof(stipple
) );
683 UNLOCK_HARDWARE( rmesa
);
686 static void r200PolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
688 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
689 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
691 /* Can't generally do unfilled via tcl, but some good special
694 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_UNFILLED
, flag
);
695 if (rmesa
->TclFallback
) {
696 r200ChooseRenderState( ctx
);
697 r200ChooseVertexState( ctx
);
702 /* =============================================================
703 * Rendering attributes
705 * We really don't want to recalculate all this every time we bind a
706 * texture. These things shouldn't change all that often, so it makes
707 * sense to break them out of the core texture state update routines.
710 /* Examine lighting and texture state to determine if separate specular
713 static void r200UpdateSpecular( GLcontext
*ctx
)
715 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
716 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
718 R200_STATECHANGE( rmesa
, tcl
);
719 R200_STATECHANGE( rmesa
, vtx
);
721 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] &= ~(3<<R200_VTX_COLOR_0_SHIFT
);
722 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] &= ~(3<<R200_VTX_COLOR_1_SHIFT
);
723 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] &= ~R200_OUTPUT_COLOR_0
;
724 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] &= ~R200_OUTPUT_COLOR_1
;
725 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_LIGHTING_ENABLE
;
727 p
&= ~R200_SPECULAR_ENABLE
;
729 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_DIFFUSE_SPECULAR_COMBINE
;
732 if (ctx
->Light
.Enabled
&&
733 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
734 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
735 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
736 (R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
));
737 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_0
;
738 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_1
;
739 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LIGHTING_ENABLE
;
740 p
|= R200_SPECULAR_ENABLE
;
741 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &=
742 ~R200_DIFFUSE_SPECULAR_COMBINE
;
744 else if (ctx
->Light
.Enabled
) {
745 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
746 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
));
747 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_0
;
748 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LIGHTING_ENABLE
;
749 } else if (ctx
->Fog
.ColorSumEnabled
) {
750 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
751 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
752 (R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
));
753 p
|= R200_SPECULAR_ENABLE
;
755 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
756 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
));
759 if (ctx
->Fog
.Enabled
) {
760 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
761 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
));
762 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_1
;
765 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
766 R200_STATECHANGE( rmesa
, ctx
);
767 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
770 /* Update vertex/render formats
772 if (rmesa
->TclFallback
) {
773 r200ChooseRenderState( ctx
);
774 r200ChooseVertexState( ctx
);
779 /* =============================================================
784 /* Update on colormaterial, material emmissive/ambient,
785 * lightmodel.globalambient
787 static void update_global_ambient( GLcontext
*ctx
)
789 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
790 float *fcmd
= (float *)R200_DB_STATE( glt
);
792 /* Need to do more if both emmissive & ambient are PREMULT:
793 * I believe this is not nessary when using source_material. This condition thus
794 * will never happen currently, and the function has no dependencies on materials now
796 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
] &
797 ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT
) |
798 (3 << R200_FRONT_AMBIENT_SOURCE_SHIFT
))) == 0)
800 COPY_3V( &fcmd
[GLT_RED
],
801 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
802 ACC_SCALE_3V( &fcmd
[GLT_RED
],
803 ctx
->Light
.Model
.Ambient
,
804 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
808 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
811 R200_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
814 /* Update on change to
818 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
820 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
822 /* fprintf(stderr, "%s\n", __FUNCTION__); */
825 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
826 float *fcmd
= (float *)R200_DB_STATE( lit
[p
] );
828 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
829 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
830 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
832 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
836 static void r200ColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
838 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
839 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
];
840 light_model_ctl1
&= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT
) |
841 (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT
) |
842 (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT
) |
843 (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT
) |
844 (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT
) |
845 (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT
) |
846 (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT
) |
847 (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT
));
849 if (ctx
->Light
.ColorMaterialEnabled
) {
850 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
852 if (mask
& MAT_BIT_FRONT_EMISSION
) {
853 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
854 R200_FRONT_EMISSIVE_SOURCE_SHIFT
);
857 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
858 R200_FRONT_EMISSIVE_SOURCE_SHIFT
);
860 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
861 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
862 R200_FRONT_AMBIENT_SOURCE_SHIFT
);
865 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
866 R200_FRONT_AMBIENT_SOURCE_SHIFT
);
868 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
869 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
870 R200_FRONT_DIFFUSE_SOURCE_SHIFT
);
873 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
874 R200_FRONT_DIFFUSE_SOURCE_SHIFT
);
876 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
877 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
878 R200_FRONT_SPECULAR_SOURCE_SHIFT
);
881 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
882 R200_FRONT_SPECULAR_SOURCE_SHIFT
);
885 if (mask
& MAT_BIT_BACK_EMISSION
) {
886 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
887 R200_BACK_EMISSIVE_SOURCE_SHIFT
);
890 else light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
891 R200_BACK_EMISSIVE_SOURCE_SHIFT
);
893 if (mask
& MAT_BIT_BACK_AMBIENT
) {
894 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
895 R200_BACK_AMBIENT_SOURCE_SHIFT
);
897 else light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
898 R200_BACK_AMBIENT_SOURCE_SHIFT
);
900 if (mask
& MAT_BIT_BACK_DIFFUSE
) {
901 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
902 R200_BACK_DIFFUSE_SOURCE_SHIFT
);
904 else light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
905 R200_BACK_DIFFUSE_SOURCE_SHIFT
);
907 if (mask
& MAT_BIT_BACK_SPECULAR
) {
908 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
909 R200_BACK_SPECULAR_SOURCE_SHIFT
);
912 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
913 R200_BACK_SPECULAR_SOURCE_SHIFT
);
917 /* Default to SOURCE_MATERIAL:
920 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_EMISSIVE_SOURCE_SHIFT
) |
921 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_AMBIENT_SOURCE_SHIFT
) |
922 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_DIFFUSE_SOURCE_SHIFT
) |
923 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_SPECULAR_SOURCE_SHIFT
) |
924 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_EMISSIVE_SOURCE_SHIFT
) |
925 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_AMBIENT_SOURCE_SHIFT
) |
926 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_DIFFUSE_SOURCE_SHIFT
) |
927 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_SPECULAR_SOURCE_SHIFT
);
930 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
]) {
931 R200_STATECHANGE( rmesa
, tcl
);
932 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
] = light_model_ctl1
;
938 void r200UpdateMaterial( GLcontext
*ctx
)
940 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
941 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
942 GLfloat
*fcmd
= (GLfloat
*)R200_DB_STATE( mtl
[0] );
943 GLfloat
*fcmd2
= (GLfloat
*)R200_DB_STATE( mtl
[1] );
946 /* Might be possible and faster to update everything unconditionally? */
947 if (ctx
->Light
.ColorMaterialEnabled
)
948 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
950 if (R200_DEBUG
& DEBUG_STATE
)
951 fprintf(stderr
, "%s\n", __FUNCTION__
);
953 if (mask
& MAT_BIT_FRONT_EMISSION
) {
954 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
955 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
956 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
957 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
959 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
960 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
961 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
962 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
963 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
965 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
966 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
967 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
968 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
969 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
971 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
972 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
973 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
974 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
975 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
977 if (mask
& MAT_BIT_FRONT_SHININESS
) {
978 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
981 if (mask
& MAT_BIT_BACK_EMISSION
) {
982 fcmd2
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_BACK_EMISSION
][0];
983 fcmd2
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_BACK_EMISSION
][1];
984 fcmd2
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_BACK_EMISSION
][2];
985 fcmd2
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_BACK_EMISSION
][3];
987 if (mask
& MAT_BIT_BACK_AMBIENT
) {
988 fcmd2
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][0];
989 fcmd2
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][1];
990 fcmd2
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][2];
991 fcmd2
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][3];
993 if (mask
& MAT_BIT_BACK_DIFFUSE
) {
994 fcmd2
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][0];
995 fcmd2
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][1];
996 fcmd2
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][2];
997 fcmd2
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][3];
999 if (mask
& MAT_BIT_BACK_SPECULAR
) {
1000 fcmd2
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][0];
1001 fcmd2
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][1];
1002 fcmd2
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][2];
1003 fcmd2
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][3];
1005 if (mask
& MAT_BIT_BACK_SHININESS
) {
1006 fcmd2
[MTL_SHININESS
] = mat
[MAT_ATTRIB_BACK_SHININESS
][0];
1009 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
[0] );
1010 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
[1] );
1012 /* currently material changes cannot trigger a global ambient change, I believe this is correct
1013 update_global_ambient( ctx ); */
1018 * _MESA_NEW_NEED_EYE_COORDS
1020 * Uses derived state from mesa:
1025 * _ModelViewInvScale
1029 * which are calculated in light.c and are correct for the current
1030 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
1031 * and _MESA_NEW_NEED_EYE_COORDS.
1033 static void update_light( GLcontext
*ctx
)
1035 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1037 /* Have to check these, or have an automatic shortcircuit mechanism
1038 * to remove noop statechanges. (Or just do a better job on the
1042 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
];
1044 if (ctx
->_NeedEyeCoords
)
1045 tmp
&= ~R200_LIGHT_IN_MODELSPACE
;
1047 tmp
|= R200_LIGHT_IN_MODELSPACE
;
1049 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
])
1051 R200_STATECHANGE( rmesa
, tcl
);
1052 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] = tmp
;
1057 GLfloat
*fcmd
= (GLfloat
*)R200_DB_STATE( eye
);
1058 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1059 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1060 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1061 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1062 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1067 if (ctx
->Light
.Enabled
) {
1069 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1070 if (ctx
->Light
.Light
[p
].Enabled
) {
1071 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1072 GLfloat
*fcmd
= (GLfloat
*)R200_DB_STATE( lit
[p
] );
1074 if (l
->EyePosition
[3] == 0.0) {
1075 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1076 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1077 fcmd
[LIT_POSITION_W
] = 0;
1078 fcmd
[LIT_DIRECTION_W
] = 0;
1080 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1081 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1082 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1083 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1084 fcmd
[LIT_DIRECTION_W
] = 0;
1087 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1093 static void r200Lightfv( GLcontext
*ctx
, GLenum light
,
1094 GLenum pname
, const GLfloat
*params
)
1096 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1097 GLint p
= light
- GL_LIGHT0
;
1098 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1099 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1106 update_light_colors( ctx
, p
);
1109 case GL_SPOT_DIRECTION
:
1110 /* picked up in update_light */
1114 /* positions picked up in update_light, but can do flag here */
1115 GLuint flag
= (p
&1)? R200_LIGHT_1_IS_LOCAL
: R200_LIGHT_0_IS_LOCAL
;
1116 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1118 R200_STATECHANGE(rmesa
, tcl
);
1119 if (l
->EyePosition
[3] != 0.0F
)
1120 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1122 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1126 case GL_SPOT_EXPONENT
:
1127 R200_STATECHANGE(rmesa
, lit
[p
]);
1128 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1131 case GL_SPOT_CUTOFF
: {
1132 GLuint flag
= (p
&1) ? R200_LIGHT_1_IS_SPOT
: R200_LIGHT_0_IS_SPOT
;
1133 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1135 R200_STATECHANGE(rmesa
, lit
[p
]);
1136 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1138 R200_STATECHANGE(rmesa
, tcl
);
1139 if (l
->SpotCutoff
!= 180.0F
)
1140 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1142 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1147 case GL_CONSTANT_ATTENUATION
:
1148 R200_STATECHANGE(rmesa
, lit
[p
]);
1149 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1150 if ( params
[0] == 0.0 )
1151 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1153 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1155 case GL_LINEAR_ATTENUATION
:
1156 R200_STATECHANGE(rmesa
, lit
[p
]);
1157 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1159 case GL_QUADRATIC_ATTENUATION
:
1160 R200_STATECHANGE(rmesa
, lit
[p
]);
1161 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1167 /* Set RANGE_ATTEN only when needed */
1170 case GL_CONSTANT_ATTENUATION
:
1171 case GL_LINEAR_ATTENUATION
:
1172 case GL_QUADRATIC_ATTENUATION
: {
1173 GLuint
*icmd
= (GLuint
*)R200_DB_STATE( tcl
);
1174 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1175 GLuint atten_flag
= ( p
&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN
1176 : R200_LIGHT_0_ENABLE_RANGE_ATTEN
;
1177 GLuint atten_const_flag
= ( p
&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN
1178 : R200_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1180 if ( l
->EyePosition
[3] == 0.0F
||
1181 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1182 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1183 /* Disable attenuation */
1184 icmd
[idx
] &= ~atten_flag
;
1186 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1187 /* Enable only constant portion of attenuation calculation */
1188 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1190 /* Enable full attenuation calculation */
1191 icmd
[idx
] &= ~atten_const_flag
;
1192 icmd
[idx
] |= atten_flag
;
1196 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1207 static void r200LightModelfv( GLcontext
*ctx
, GLenum pname
,
1208 const GLfloat
*param
)
1210 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1213 case GL_LIGHT_MODEL_AMBIENT
:
1214 update_global_ambient( ctx
);
1217 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1218 R200_STATECHANGE( rmesa
, tcl
);
1219 if (ctx
->Light
.Model
.LocalViewer
)
1220 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LOCAL_VIEWER
;
1222 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_LOCAL_VIEWER
;
1225 case GL_LIGHT_MODEL_TWO_SIDE
:
1226 R200_STATECHANGE( rmesa
, tcl
);
1227 if (ctx
->Light
.Model
.TwoSide
)
1228 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LIGHT_TWOSIDE
;
1230 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~(R200_LIGHT_TWOSIDE
);
1231 if (rmesa
->TclFallback
) {
1232 r200ChooseRenderState( ctx
);
1233 r200ChooseVertexState( ctx
);
1237 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1238 r200UpdateSpecular(ctx
);
1246 static void r200ShadeModel( GLcontext
*ctx
, GLenum mode
)
1248 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1249 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1251 s
&= ~(R200_DIFFUSE_SHADE_MASK
|
1252 R200_ALPHA_SHADE_MASK
|
1253 R200_SPECULAR_SHADE_MASK
|
1254 R200_FOG_SHADE_MASK
);
1258 s
|= (R200_DIFFUSE_SHADE_FLAT
|
1259 R200_ALPHA_SHADE_FLAT
|
1260 R200_SPECULAR_SHADE_FLAT
|
1261 R200_FOG_SHADE_FLAT
);
1264 s
|= (R200_DIFFUSE_SHADE_GOURAUD
|
1265 R200_ALPHA_SHADE_GOURAUD
|
1266 R200_SPECULAR_SHADE_GOURAUD
|
1267 R200_FOG_SHADE_GOURAUD
);
1273 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1274 R200_STATECHANGE( rmesa
, set
);
1275 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1280 /* =============================================================
1284 static void r200ClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1286 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1287 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1288 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1290 R200_STATECHANGE( rmesa
, ucp
[p
] );
1291 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1292 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1293 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1294 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1297 static void r200UpdateClipPlanes( GLcontext
*ctx
)
1299 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1302 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1303 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1304 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1306 R200_STATECHANGE( rmesa
, ucp
[p
] );
1307 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1308 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1309 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1310 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1316 /* =============================================================
1320 static void r200StencilFunc( GLcontext
*ctx
, GLenum func
,
1321 GLint ref
, GLuint mask
)
1323 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1324 GLuint refmask
= ((ctx
->Stencil
.Ref
[0] << R200_STENCIL_REF_SHIFT
) |
1325 (ctx
->Stencil
.ValueMask
[0] << R200_STENCIL_MASK_SHIFT
));
1327 R200_STATECHANGE( rmesa
, ctx
);
1328 R200_STATECHANGE( rmesa
, msk
);
1330 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~R200_STENCIL_TEST_MASK
;
1331 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(R200_STENCIL_REF_MASK
|
1332 R200_STENCIL_VALUE_MASK
);
1334 switch ( ctx
->Stencil
.Function
[0] ) {
1336 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_NEVER
;
1339 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_LESS
;
1342 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_EQUAL
;
1345 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_LEQUAL
;
1348 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_GREATER
;
1351 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_NEQUAL
;
1354 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_GEQUAL
;
1357 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_ALWAYS
;
1361 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1364 static void r200StencilMask( GLcontext
*ctx
, GLuint mask
)
1366 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1368 R200_STATECHANGE( rmesa
, msk
);
1369 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~R200_STENCIL_WRITE_MASK
;
1370 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1371 (ctx
->Stencil
.WriteMask
[0] << R200_STENCIL_WRITEMASK_SHIFT
);
1374 static void r200StencilOp( GLcontext
*ctx
, GLenum fail
,
1375 GLenum zfail
, GLenum zpass
)
1377 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1379 R200_STATECHANGE( rmesa
, ctx
);
1380 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(R200_STENCIL_FAIL_MASK
|
1381 R200_STENCIL_ZFAIL_MASK
|
1382 R200_STENCIL_ZPASS_MASK
);
1384 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1386 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_KEEP
;
1389 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_ZERO
;
1392 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_REPLACE
;
1395 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_INC
;
1398 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_DEC
;
1400 case GL_INCR_WRAP_EXT
:
1401 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_INC_WRAP
;
1403 case GL_DECR_WRAP_EXT
:
1404 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_DEC_WRAP
;
1407 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_INVERT
;
1411 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1413 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_KEEP
;
1416 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_ZERO
;
1419 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_REPLACE
;
1422 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_INC
;
1425 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_DEC
;
1427 case GL_INCR_WRAP_EXT
:
1428 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_INC_WRAP
;
1430 case GL_DECR_WRAP_EXT
:
1431 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_DEC_WRAP
;
1434 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_INVERT
;
1438 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1440 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_KEEP
;
1443 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_ZERO
;
1446 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_REPLACE
;
1449 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_INC
;
1452 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_DEC
;
1454 case GL_INCR_WRAP_EXT
:
1455 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_INC_WRAP
;
1457 case GL_DECR_WRAP_EXT
:
1458 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_DEC_WRAP
;
1461 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_INVERT
;
1466 static void r200ClearStencil( GLcontext
*ctx
, GLint s
)
1468 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1470 rmesa
->state
.stencil
.clear
=
1471 ((GLuint
) ctx
->Stencil
.Clear
|
1472 (0xff << R200_STENCIL_MASK_SHIFT
) |
1473 (ctx
->Stencil
.WriteMask
[0] << R200_STENCIL_WRITEMASK_SHIFT
));
1477 /* =============================================================
1478 * Window position and viewport transformation
1482 * To correctly position primitives:
1484 #define SUBPIXEL_X 0.125
1485 #define SUBPIXEL_Y 0.125
1487 void r200UpdateWindow( GLcontext
*ctx
)
1489 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1490 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1491 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1492 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1493 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1495 GLfloat sx
= v
[MAT_SX
];
1496 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1497 GLfloat sy
= - v
[MAT_SY
];
1498 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1499 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1500 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1502 R200_FIREVERTICES( rmesa
);
1503 R200_STATECHANGE( rmesa
, vpt
);
1505 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = *(GLuint
*)&sx
;
1506 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1507 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = *(GLuint
*)&sy
;
1508 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1509 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = *(GLuint
*)&sz
;
1510 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = *(GLuint
*)&tz
;
1515 static void r200Viewport( GLcontext
*ctx
, GLint x
, GLint y
,
1516 GLsizei width
, GLsizei height
)
1518 /* Don't pipeline viewport changes, conflict with window offset
1519 * setting below. Could apply deltas to rescue pipelined viewport
1520 * values, or keep the originals hanging around.
1522 R200_FIREVERTICES( R200_CONTEXT(ctx
) );
1523 r200UpdateWindow( ctx
);
1526 static void r200DepthRange( GLcontext
*ctx
, GLclampd nearval
,
1529 r200UpdateWindow( ctx
);
1532 void r200UpdateViewportOffset( GLcontext
*ctx
)
1534 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1535 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1536 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1537 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1538 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1540 GLfloat tx
= v
[MAT_TX
] + xoffset
;
1541 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
;
1543 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != *(GLuint
*)&tx
||
1544 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != *(GLuint
*)&ty
)
1546 /* Note: this should also modify whatever data the context reset
1549 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1550 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1552 /* update polygon stipple x/y screen offset */
1555 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1557 m
&= ~(R200_STIPPLE_X_OFFSET_MASK
|
1558 R200_STIPPLE_Y_OFFSET_MASK
);
1560 /* add magic offsets, then invert */
1561 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & R200_STIPPLE_COORD_MASK
);
1562 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1563 & R200_STIPPLE_COORD_MASK
);
1565 m
|= ((stx
<< R200_STIPPLE_X_OFFSET_SHIFT
) |
1566 (sty
<< R200_STIPPLE_Y_OFFSET_SHIFT
));
1568 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1569 R200_STATECHANGE( rmesa
, msc
);
1570 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1575 r200UpdateScissor( ctx
);
1580 /* =============================================================
1584 static void r200ClearColor( GLcontext
*ctx
, const GLfloat c
[4] )
1586 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1588 CLAMPED_FLOAT_TO_UBYTE(color
[0], c
[0]);
1589 CLAMPED_FLOAT_TO_UBYTE(color
[1], c
[1]);
1590 CLAMPED_FLOAT_TO_UBYTE(color
[2], c
[2]);
1591 CLAMPED_FLOAT_TO_UBYTE(color
[3], c
[3]);
1592 rmesa
->state
.color
.clear
= r200PackColor( rmesa
->r200Screen
->cpp
,
1594 color
[2], color
[3] );
1598 static void r200RenderMode( GLcontext
*ctx
, GLenum mode
)
1600 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1601 FALLBACK( rmesa
, R200_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1605 static GLuint r200_rop_tab
[] = {
1608 R200_ROP_AND_REVERSE
,
1610 R200_ROP_AND_INVERTED
,
1617 R200_ROP_OR_REVERSE
,
1618 R200_ROP_COPY_INVERTED
,
1619 R200_ROP_OR_INVERTED
,
1624 static void r200LogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1626 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1627 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1631 R200_STATECHANGE( rmesa
, msk
);
1632 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = r200_rop_tab
[rop
];
1636 void r200SetCliprects( r200ContextPtr rmesa
, GLenum mode
)
1638 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1642 rmesa
->numClipRects
= dPriv
->numClipRects
;
1643 rmesa
->pClipRects
= dPriv
->pClipRects
;
1646 /* Can't ignore 2d windows if we are page flipping.
1648 if ( dPriv
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1649 rmesa
->numClipRects
= dPriv
->numClipRects
;
1650 rmesa
->pClipRects
= dPriv
->pClipRects
;
1653 rmesa
->numClipRects
= dPriv
->numBackClipRects
;
1654 rmesa
->pClipRects
= dPriv
->pBackClipRects
;
1658 fprintf(stderr
, "bad mode in r200SetCliprects\n");
1662 if (rmesa
->state
.scissor
.enabled
)
1663 r200RecalcScissorRects( rmesa
);
1667 static void r200DrawBuffer( GLcontext
*ctx
, GLenum mode
)
1669 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1671 if (R200_DEBUG
& DEBUG_DRI
)
1672 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1673 _mesa_lookup_enum_by_nr( mode
));
1675 R200_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1678 * _DrawDestMask is easier to cope with than <mode>.
1680 switch ( ctx
->Color
._DrawDestMask
) {
1681 case DD_FRONT_LEFT_BIT
:
1682 FALLBACK( rmesa
, R200_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1683 r200SetCliprects( rmesa
, GL_FRONT_LEFT
);
1685 case DD_BACK_LEFT_BIT
:
1686 FALLBACK( rmesa
, R200_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1687 r200SetCliprects( rmesa
, GL_BACK_LEFT
);
1690 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
1691 FALLBACK( rmesa
, R200_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1695 /* We want to update the s/w rast state too so that r200SetBuffer()
1698 _swrast_DrawBuffer(ctx
, mode
);
1700 R200_STATECHANGE( rmesa
, ctx
);
1701 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
] = ((rmesa
->state
.color
.drawOffset
+
1702 rmesa
->r200Screen
->fbLocation
)
1703 & R200_COLOROFFSET_MASK
);
1704 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = rmesa
->state
.color
.drawPitch
;
1708 static void r200ReadBuffer( GLcontext
*ctx
, GLenum mode
)
1710 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1713 /* =============================================================
1714 * State enable/disable
1717 static void r200Enable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1719 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1722 if ( R200_DEBUG
& DEBUG_STATE
)
1723 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1724 _mesa_lookup_enum_by_nr( cap
),
1725 state
? "GL_TRUE" : "GL_FALSE" );
1728 /* Fast track this one...
1736 R200_STATECHANGE( rmesa
, ctx
);
1738 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_ALPHA_TEST_ENABLE
;
1740 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_ALPHA_TEST_ENABLE
;
1745 case GL_COLOR_LOGIC_OP
:
1746 r200_set_blend_state( ctx
);
1749 case GL_CLIP_PLANE0
:
1750 case GL_CLIP_PLANE1
:
1751 case GL_CLIP_PLANE2
:
1752 case GL_CLIP_PLANE3
:
1753 case GL_CLIP_PLANE4
:
1754 case GL_CLIP_PLANE5
:
1755 p
= cap
-GL_CLIP_PLANE0
;
1756 R200_STATECHANGE( rmesa
, tcl
);
1758 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (R200_UCP_ENABLE_0
<<p
);
1759 r200ClipPlane( ctx
, cap
, NULL
);
1762 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(R200_UCP_ENABLE_0
<<p
);
1766 case GL_COLOR_MATERIAL
:
1767 r200ColorMaterial( ctx
, 0, 0 );
1768 r200UpdateMaterial( ctx
);
1772 r200CullFace( ctx
, 0 );
1776 R200_STATECHANGE(rmesa
, ctx
);
1778 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_Z_ENABLE
;
1780 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_Z_ENABLE
;
1785 R200_STATECHANGE(rmesa
, ctx
);
1787 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_DITHER_ENABLE
;
1788 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1790 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_DITHER_ENABLE
;
1791 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1796 R200_STATECHANGE(rmesa
, ctx
);
1798 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_FOG_ENABLE
;
1799 r200Fogfv( ctx
, GL_FOG_MODE
, 0 );
1801 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_FOG_ENABLE
;
1802 R200_STATECHANGE(rmesa
, tcl
);
1803 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~R200_TCL_FOG_MASK
;
1805 r200UpdateSpecular( ctx
); /* for PK_SPEC */
1806 if (rmesa
->TclFallback
)
1807 r200ChooseVertexState( ctx
);
1808 _mesa_allow_light_in_model( ctx
, !state
);
1819 R200_STATECHANGE(rmesa
, tcl
);
1820 p
= cap
- GL_LIGHT0
;
1822 flag
= (R200_LIGHT_1_ENABLE
|
1823 R200_LIGHT_1_ENABLE_AMBIENT
|
1824 R200_LIGHT_1_ENABLE_SPECULAR
);
1826 flag
= (R200_LIGHT_0_ENABLE
|
1827 R200_LIGHT_0_ENABLE_AMBIENT
|
1828 R200_LIGHT_0_ENABLE_SPECULAR
);
1831 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1833 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1837 update_light_colors( ctx
, p
);
1841 r200UpdateSpecular(ctx
);
1844 case GL_LINE_SMOOTH
:
1845 R200_STATECHANGE( rmesa
, ctx
);
1847 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_ANTI_ALIAS_LINE
;
1849 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_ANTI_ALIAS_LINE
;
1853 case GL_LINE_STIPPLE
:
1854 R200_STATECHANGE( rmesa
, set
);
1856 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] |= R200_PATTERN_ENABLE
;
1858 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] &= ~R200_PATTERN_ENABLE
;
1863 R200_STATECHANGE( rmesa
, tcl
);
1865 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_NORMALIZE_NORMALS
;
1867 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_NORMALIZE_NORMALS
;
1871 /* Pointsize registers on r200 don't seem to do anything. Maybe
1872 * have to pass pointsizes as vertex parameters? In any case,
1873 * setting pointmin == pointsizemax == 1.0, and doing nothing
1874 * for aa is enough to satisfy conform.
1876 case GL_POINT_SMOOTH
:
1879 /* These don't really do anything, as we don't use the 3vtx
1883 case GL_POLYGON_OFFSET_POINT
:
1884 R200_STATECHANGE( rmesa
, set
);
1886 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_ZBIAS_ENABLE_POINT
;
1888 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_ZBIAS_ENABLE_POINT
;
1892 case GL_POLYGON_OFFSET_LINE
:
1893 R200_STATECHANGE( rmesa
, set
);
1895 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_ZBIAS_ENABLE_LINE
;
1897 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_ZBIAS_ENABLE_LINE
;
1902 case GL_POLYGON_OFFSET_FILL
:
1903 R200_STATECHANGE( rmesa
, set
);
1905 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_ZBIAS_ENABLE_TRI
;
1907 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_ZBIAS_ENABLE_TRI
;
1911 case GL_POLYGON_SMOOTH
:
1912 R200_STATECHANGE( rmesa
, ctx
);
1914 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_ANTI_ALIAS_POLY
;
1916 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_ANTI_ALIAS_POLY
;
1920 case GL_POLYGON_STIPPLE
:
1921 R200_STATECHANGE(rmesa
, set
);
1923 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] |= R200_STIPPLE_ENABLE
;
1925 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] &= ~R200_STIPPLE_ENABLE
;
1929 case GL_RESCALE_NORMAL_EXT
: {
1930 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1931 R200_STATECHANGE( rmesa
, tcl
);
1933 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_RESCALE_NORMALS
;
1935 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_RESCALE_NORMALS
;
1940 case GL_SCISSOR_TEST
:
1941 R200_FIREVERTICES( rmesa
);
1942 rmesa
->state
.scissor
.enabled
= state
;
1943 r200UpdateScissor( ctx
);
1946 case GL_STENCIL_TEST
:
1947 if ( rmesa
->state
.stencil
.hwBuffer
) {
1948 R200_STATECHANGE( rmesa
, ctx
);
1950 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_STENCIL_ENABLE
;
1952 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_STENCIL_ENABLE
;
1955 FALLBACK( rmesa
, R200_FALLBACK_STENCIL
, state
);
1959 case GL_TEXTURE_GEN_Q
:
1960 case GL_TEXTURE_GEN_R
:
1961 case GL_TEXTURE_GEN_S
:
1962 case GL_TEXTURE_GEN_T
:
1963 /* Picked up in r200UpdateTextureState.
1965 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1968 case GL_COLOR_SUM_EXT
:
1969 r200UpdateSpecular ( ctx
);
1978 void r200LightingSpaceChange( GLcontext
*ctx
)
1980 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1983 if (R200_DEBUG
& DEBUG_STATE
)
1984 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1985 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
]);
1987 if (ctx
->_NeedEyeCoords
)
1988 tmp
= ctx
->Transform
.RescaleNormals
;
1990 tmp
= !ctx
->Transform
.RescaleNormals
;
1992 R200_STATECHANGE( rmesa
, tcl
);
1994 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_RESCALE_NORMALS
;
1996 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_RESCALE_NORMALS
;
1999 if (R200_DEBUG
& DEBUG_STATE
)
2000 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2001 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
]);
2004 /* =============================================================
2005 * Deferred state management - matrices, textures, other?
2011 static void upload_matrix( r200ContextPtr rmesa
, GLfloat
*src
, int idx
)
2013 float *dest
= ((float *)R200_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2017 for (i
= 0 ; i
< 4 ; i
++) {
2021 *dest
++ = src
[i
+12];
2024 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2027 static void upload_matrix_t( r200ContextPtr rmesa
, const GLfloat
*src
, int idx
)
2029 float *dest
= ((float *)R200_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2030 memcpy(dest
, src
, 16*sizeof(float));
2031 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2035 static void update_texturematrix( GLcontext
*ctx
)
2037 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
2038 GLuint tpc
= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_0
];
2039 GLuint compsel
= rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
];
2042 if (R200_DEBUG
& DEBUG_STATE
)
2043 fprintf(stderr
, "%s before COMPSEL: %x\n", __FUNCTION__
,
2044 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
]);
2046 rmesa
->TexMatEnabled
= 0;
2047 rmesa
->TexMatCompSel
= 0;
2049 for (unit
= 0 ; unit
< 2; unit
++) {
2050 if (!ctx
->Texture
.Unit
[unit
]._ReallyEnabled
)
2053 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2054 rmesa
->TexMatEnabled
|= (R200_TEXGEN_TEXMAT_0_ENABLE
|
2055 R200_TEXMAT_0_ENABLE
) << unit
;
2057 rmesa
->TexMatCompSel
|= R200_OUTPUT_TEX_0
<< unit
;
2059 if (rmesa
->TexGenEnabled
& (R200_TEXMAT_0_ENABLE
<< unit
)) {
2060 /* Need to preconcatenate any active texgen
2061 * obj/eyeplane matrices:
2063 _math_matrix_mul_matrix( &rmesa
->tmpmat
,
2064 &rmesa
->TexGenMatrix
[unit
],
2065 ctx
->TextureMatrixStack
[unit
].Top
);
2066 upload_matrix( rmesa
, rmesa
->tmpmat
.m
, R200_MTX_TEX0
+unit
);
2069 upload_matrix( rmesa
, ctx
->TextureMatrixStack
[unit
].Top
->m
,
2070 R200_MTX_TEX0
+unit
);
2073 else if (rmesa
->TexGenEnabled
& (R200_TEXMAT_0_ENABLE
<< unit
)) {
2074 upload_matrix( rmesa
, rmesa
->TexGenMatrix
[unit
].m
,
2075 R200_MTX_TEX0
+unit
);
2079 tpc
= (rmesa
->TexMatEnabled
| rmesa
->TexGenEnabled
);
2080 if (tpc
!= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_0
] ||
2081 rmesa
->TexGenInputs
!= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
]) {
2082 R200_STATECHANGE(rmesa
, tcg
);
2083 rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_0
] = tpc
;
2084 rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
] = rmesa
->TexGenInputs
;
2087 compsel
&= ~R200_OUTPUT_TEX_MASK
;
2088 compsel
|= rmesa
->TexMatCompSel
| rmesa
->TexGenCompSel
;
2089 if (compsel
!= rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
]) {
2090 R200_STATECHANGE(rmesa
, vtx
);
2091 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] = compsel
;
2097 void r200ValidateState( GLcontext
*ctx
)
2099 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
2100 GLuint new_state
= rmesa
->NewGLState
;
2102 if (new_state
& _NEW_TEXTURE
) {
2103 r200UpdateTextureState( ctx
);
2104 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2107 /* Need an event driven matrix update?
2109 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2110 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, R200_MTX_MVP
);
2112 /* Need these for lighting (shouldn't upload otherwise)
2114 if (new_state
& (_NEW_MODELVIEW
)) {
2115 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, R200_MTX_MV
);
2116 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, R200_MTX_IMV
);
2119 /* Does this need to be triggered on eg. modelview for
2120 * texgen-derived objplane/eyeplane matrices?
2122 if (new_state
& (_NEW_TEXTURE
|_NEW_TEXTURE_MATRIX
)) {
2123 update_texturematrix( ctx
);
2126 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2127 update_light( ctx
);
2130 /* emit all active clip planes if projection matrix changes.
2132 if (new_state
& (_NEW_PROJECTION
)) {
2133 if (ctx
->Transform
.ClipPlanesEnabled
)
2134 r200UpdateClipPlanes( ctx
);
2138 rmesa
->NewGLState
= 0;
2142 static void r200InvalidateState( GLcontext
*ctx
, GLuint new_state
)
2144 _swrast_InvalidateState( ctx
, new_state
);
2145 _swsetup_InvalidateState( ctx
, new_state
);
2146 _ac_InvalidateState( ctx
, new_state
);
2147 _tnl_InvalidateState( ctx
, new_state
);
2148 _ae_invalidate_state( ctx
, new_state
);
2149 R200_CONTEXT(ctx
)->NewGLState
|= new_state
;
2150 r200VtxfmtInvalidate( ctx
);
2153 /* A hack. The r200 can actually cope just fine with materials
2154 * between begin/ends, so fix this. But how ?
2156 static GLboolean
check_material( GLcontext
*ctx
)
2158 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2161 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2162 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2164 if (tnl
->vb
.AttribPtr
[i
] &&
2165 tnl
->vb
.AttribPtr
[i
]->stride
)
2171 static void r200WrapRunPipeline( GLcontext
*ctx
)
2173 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
2174 GLboolean has_material
;
2177 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2181 if (rmesa
->NewGLState
)
2182 r200ValidateState( ctx
);
2184 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2187 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2190 /* Run the pipeline.
2192 _tnl_run_pipeline( ctx
);
2195 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2200 /* Initialize the driver's state functions.
2202 void r200InitStateFuncs( struct dd_function_table
*functions
)
2204 functions
->UpdateState
= r200InvalidateState
;
2205 functions
->LightingSpaceChange
= r200LightingSpaceChange
;
2207 functions
->DrawBuffer
= r200DrawBuffer
;
2208 functions
->ReadBuffer
= r200ReadBuffer
;
2210 functions
->AlphaFunc
= r200AlphaFunc
;
2211 functions
->BlendEquationSeparate
= r200BlendEquationSeparate
;
2212 functions
->BlendFuncSeparate
= r200BlendFuncSeparate
;
2213 functions
->ClearColor
= r200ClearColor
;
2214 functions
->ClearDepth
= NULL
;
2215 functions
->ClearIndex
= NULL
;
2216 functions
->ClearStencil
= r200ClearStencil
;
2217 functions
->ClipPlane
= r200ClipPlane
;
2218 functions
->ColorMask
= r200ColorMask
;
2219 functions
->CullFace
= r200CullFace
;
2220 functions
->DepthFunc
= r200DepthFunc
;
2221 functions
->DepthMask
= r200DepthMask
;
2222 functions
->DepthRange
= r200DepthRange
;
2223 functions
->Enable
= r200Enable
;
2224 functions
->Fogfv
= r200Fogfv
;
2225 functions
->FrontFace
= r200FrontFace
;
2226 functions
->Hint
= NULL
;
2227 functions
->IndexMask
= NULL
;
2228 functions
->LightModelfv
= r200LightModelfv
;
2229 functions
->Lightfv
= r200Lightfv
;
2230 functions
->LineStipple
= r200LineStipple
;
2231 functions
->LineWidth
= r200LineWidth
;
2232 functions
->LogicOpcode
= r200LogicOpCode
;
2233 functions
->PolygonMode
= r200PolygonMode
;
2234 functions
->PolygonOffset
= r200PolygonOffset
;
2235 functions
->PolygonStipple
= r200PolygonStipple
;
2236 functions
->PointSize
= r200PointSize
;
2237 functions
->RenderMode
= r200RenderMode
;
2238 functions
->Scissor
= r200Scissor
;
2239 functions
->ShadeModel
= r200ShadeModel
;
2240 functions
->StencilFunc
= r200StencilFunc
;
2241 functions
->StencilMask
= r200StencilMask
;
2242 functions
->StencilOp
= r200StencilOp
;
2243 functions
->Viewport
= r200Viewport
;
2245 /* Swrast hooks for imaging extensions:
2247 functions
->CopyColorTable
= _swrast_CopyColorTable
;
2248 functions
->CopyColorSubTable
= _swrast_CopyColorSubTable
;
2249 functions
->CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
2250 functions
->CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
2254 void r200InitTnlFuncs( GLcontext
*ctx
)
2256 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= r200UpdateMaterial
;
2257 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= r200WrapRunPipeline
;