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 r200BlendEquationSeparate( GLcontext
*ctx
,
108 GLenum modeRGB
, GLenum modeA
)
110 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
111 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~R200_COMB_FCN_MASK
;
113 assert( modeRGB
== modeA
);
118 b
|= R200_COMB_FCN_ADD_CLAMP
;
121 case GL_FUNC_SUBTRACT
:
122 b
|= R200_COMB_FCN_SUB_CLAMP
;
125 case GL_FUNC_REVERSE_SUBTRACT
:
126 b
|= R200_COMB_FCN_RSUB_CLAMP
;
130 b
|= R200_COMB_FCN_MIN
;
134 b
|= R200_COMB_FCN_MAX
;
141 R200_STATECHANGE( rmesa
, ctx
);
142 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
143 if ( ctx
->Color
._LogicOpEnabled
) {
144 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_ROP_ENABLE
;
146 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_ROP_ENABLE
;
150 static void r200BlendFuncSeparate( GLcontext
*ctx
,
151 GLenum sfactorRGB
, GLenum dfactorRGB
,
152 GLenum sfactorA
, GLenum dfactorA
)
154 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
155 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
156 ~(R200_SRC_BLEND_MASK
| R200_DST_BLEND_MASK
);
158 switch ( ctx
->Color
.BlendSrcRGB
) {
160 b
|= R200_SRC_BLEND_GL_ZERO
;
163 b
|= R200_SRC_BLEND_GL_ONE
;
166 b
|= R200_SRC_BLEND_GL_DST_COLOR
;
168 case GL_ONE_MINUS_DST_COLOR
:
169 b
|= R200_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
172 b
|= R200_SRC_BLEND_GL_SRC_COLOR
;
174 case GL_ONE_MINUS_SRC_COLOR
:
175 b
|= R200_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
178 b
|= R200_SRC_BLEND_GL_SRC_ALPHA
;
180 case GL_ONE_MINUS_SRC_ALPHA
:
181 b
|= R200_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
184 b
|= R200_SRC_BLEND_GL_DST_ALPHA
;
186 case GL_ONE_MINUS_DST_ALPHA
:
187 b
|= R200_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
189 case GL_SRC_ALPHA_SATURATE
:
190 b
|= R200_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
192 case GL_CONSTANT_COLOR
:
193 b
|= R200_SRC_BLEND_GL_CONST_COLOR
;
195 case GL_ONE_MINUS_CONSTANT_COLOR
:
196 b
|= R200_SRC_BLEND_GL_ONE_MINUS_CONST_COLOR
;
198 case GL_CONSTANT_ALPHA
:
199 b
|= R200_SRC_BLEND_GL_CONST_ALPHA
;
201 case GL_ONE_MINUS_CONSTANT_ALPHA
:
202 b
|= R200_SRC_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
208 switch ( ctx
->Color
.BlendDstRGB
) {
210 b
|= R200_DST_BLEND_GL_ZERO
;
213 b
|= R200_DST_BLEND_GL_ONE
;
216 b
|= R200_DST_BLEND_GL_SRC_COLOR
;
218 case GL_ONE_MINUS_SRC_COLOR
:
219 b
|= R200_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
222 b
|= R200_DST_BLEND_GL_SRC_ALPHA
;
224 case GL_ONE_MINUS_SRC_ALPHA
:
225 b
|= R200_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
228 b
|= R200_DST_BLEND_GL_DST_COLOR
;
230 case GL_ONE_MINUS_DST_COLOR
:
231 b
|= R200_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
234 b
|= R200_DST_BLEND_GL_DST_ALPHA
;
236 case GL_ONE_MINUS_DST_ALPHA
:
237 b
|= R200_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
239 case GL_CONSTANT_COLOR
:
240 b
|= R200_DST_BLEND_GL_CONST_COLOR
;
242 case GL_ONE_MINUS_CONSTANT_COLOR
:
243 b
|= R200_DST_BLEND_GL_ONE_MINUS_CONST_COLOR
;
245 case GL_CONSTANT_ALPHA
:
246 b
|= R200_DST_BLEND_GL_CONST_ALPHA
;
248 case GL_ONE_MINUS_CONSTANT_ALPHA
:
249 b
|= R200_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
255 R200_STATECHANGE( rmesa
, ctx
);
256 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
260 /* =============================================================
264 static void r200DepthFunc( GLcontext
*ctx
, GLenum func
)
266 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
268 R200_STATECHANGE( rmesa
, ctx
);
269 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~R200_Z_TEST_MASK
;
271 switch ( ctx
->Depth
.Func
) {
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_NEVER
;
276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_LESS
;
279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_EQUAL
;
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_LEQUAL
;
285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_GREATER
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_NEQUAL
;
291 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_GEQUAL
;
294 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_TEST_ALWAYS
;
300 static void r200DepthMask( GLcontext
*ctx
, GLboolean flag
)
302 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
303 R200_STATECHANGE( rmesa
, ctx
);
305 if ( ctx
->Depth
.Mask
) {
306 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_Z_WRITE_ENABLE
;
308 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~R200_Z_WRITE_ENABLE
;
313 /* =============================================================
318 static void r200Fogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
320 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
321 union { int i
; float f
; } c
, d
;
325 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
326 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
330 if (!ctx
->Fog
.Enabled
)
332 R200_STATECHANGE(rmesa
, tcl
);
333 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~R200_TCL_FOG_MASK
;
334 switch (ctx
->Fog
.Mode
) {
336 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_TCL_FOG_LINEAR
;
337 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
342 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
343 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
347 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_TCL_FOG_EXP
;
349 d
.f
= -ctx
->Fog
.Density
;
352 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_TCL_FOG_EXP2
;
354 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
361 switch (ctx
->Fog
.Mode
) {
364 d
.f
= -ctx
->Fog
.Density
;
368 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
376 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
377 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
381 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
382 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
387 R200_STATECHANGE( rmesa
, ctx
);
388 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
389 i
= r200PackColor( 4, col
[0], col
[1], col
[2], 0 );
390 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~R200_FOG_COLOR_MASK
;
391 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |= i
;
393 case GL_FOG_COORDINATE_SOURCE_EXT
:
401 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
402 R200_STATECHANGE( rmesa
, fog
);
403 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
404 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
409 /* =============================================================
414 static GLboolean
intersect_rect( drm_clip_rect_t
*out
,
419 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
420 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
421 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
422 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
423 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
424 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
429 void r200RecalcScissorRects( r200ContextPtr rmesa
)
431 drm_clip_rect_t
*out
;
434 /* Grow cliprect store?
436 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
437 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
438 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
439 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
442 if (rmesa
->state
.scissor
.pClipRects
)
443 FREE(rmesa
->state
.scissor
.pClipRects
);
445 rmesa
->state
.scissor
.pClipRects
=
446 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
447 sizeof(drm_clip_rect_t
) );
449 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
450 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
455 out
= rmesa
->state
.scissor
.pClipRects
;
456 rmesa
->state
.scissor
.numClipRects
= 0;
458 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
459 if ( intersect_rect( out
,
460 &rmesa
->pClipRects
[i
],
461 &rmesa
->state
.scissor
.rect
) ) {
462 rmesa
->state
.scissor
.numClipRects
++;
469 static void r200UpdateScissor( GLcontext
*ctx
)
471 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
473 if ( rmesa
->dri
.drawable
) {
474 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
476 int x
= ctx
->Scissor
.X
;
477 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
478 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
479 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
481 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
482 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
483 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
484 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
486 r200RecalcScissorRects( rmesa
);
491 static void r200Scissor( GLcontext
*ctx
,
492 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
494 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
496 if ( ctx
->Scissor
.Enabled
) {
497 R200_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
498 r200UpdateScissor( ctx
);
504 /* =============================================================
508 static void r200CullFace( GLcontext
*ctx
, GLenum unused
)
510 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
511 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
512 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
514 s
|= R200_FFACE_SOLID
| R200_BFACE_SOLID
;
515 t
&= ~(R200_CULL_FRONT
| R200_CULL_BACK
);
517 if ( ctx
->Polygon
.CullFlag
) {
518 switch ( ctx
->Polygon
.CullFaceMode
) {
520 s
&= ~R200_FFACE_SOLID
;
521 t
|= R200_CULL_FRONT
;
524 s
&= ~R200_BFACE_SOLID
;
527 case GL_FRONT_AND_BACK
:
528 s
&= ~(R200_FFACE_SOLID
| R200_BFACE_SOLID
);
529 t
|= (R200_CULL_FRONT
| R200_CULL_BACK
);
534 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
535 R200_STATECHANGE(rmesa
, set
);
536 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
539 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
540 R200_STATECHANGE(rmesa
, tcl
);
541 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
545 static void r200FrontFace( GLcontext
*ctx
, GLenum mode
)
547 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
549 R200_STATECHANGE( rmesa
, set
);
550 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_FFACE_CULL_DIR_MASK
;
552 R200_STATECHANGE( rmesa
, tcl
);
553 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~R200_CULL_FRONT_IS_CCW
;
557 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_FFACE_CULL_CW
;
560 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_FFACE_CULL_CCW
;
561 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= R200_CULL_FRONT_IS_CCW
;
566 /* =============================================================
569 static void r200PointSize( GLcontext
*ctx
, GLfloat size
)
571 if (0) fprintf(stderr
, "%s: %f\n", __FUNCTION__
, size
);
574 /* =============================================================
577 static void r200LineWidth( GLcontext
*ctx
, GLfloat widthf
)
579 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
581 R200_STATECHANGE( rmesa
, lin
);
582 R200_STATECHANGE( rmesa
, set
);
584 /* Line width is stored in U6.4 format.
586 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] &= ~0xffff;
587 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] |= (GLuint
)(ctx
->Line
._Width
* 16.0);
589 if ( widthf
> 1.0 ) {
590 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_WIDELINE_ENABLE
;
592 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_WIDELINE_ENABLE
;
596 static void r200LineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
598 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
600 R200_STATECHANGE( rmesa
, lin
);
601 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
602 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
606 /* =============================================================
609 static void r200ColorMask( GLcontext
*ctx
,
610 GLboolean r
, GLboolean g
,
611 GLboolean b
, GLboolean a
)
613 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
614 GLuint mask
= r200PackColor( rmesa
->r200Screen
->cpp
,
615 ctx
->Color
.ColorMask
[RCOMP
],
616 ctx
->Color
.ColorMask
[GCOMP
],
617 ctx
->Color
.ColorMask
[BCOMP
],
618 ctx
->Color
.ColorMask
[ACOMP
] );
620 GLuint flag
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] & ~R200_PLANE_MASK_ENABLE
;
622 if (!(r
&& g
&& b
&& a
))
623 flag
|= R200_PLANE_MASK_ENABLE
;
625 if ( rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] != flag
) {
626 R200_STATECHANGE( rmesa
, ctx
);
627 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] = flag
;
630 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
631 R200_STATECHANGE( rmesa
, msk
);
632 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
637 /* =============================================================
641 static void r200PolygonOffset( GLcontext
*ctx
,
642 GLfloat factor
, GLfloat units
)
644 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
645 GLfloat constant
= units
* rmesa
->state
.depth
.scale
;
650 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
652 R200_STATECHANGE( rmesa
, zbs
);
653 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = *(GLuint
*)&factor
;
654 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = *(GLuint
*)&constant
;
657 static void r200PolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
659 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
661 drm_radeon_stipple_t stipple
;
663 /* Must flip pattern upside down.
665 for ( i
= 0 ; i
< 32 ; i
++ ) {
666 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
669 /* TODO: push this into cmd mechanism
671 R200_FIREVERTICES( rmesa
);
672 LOCK_HARDWARE( rmesa
);
674 /* FIXME: Use window x,y offsets into stipple RAM.
676 stipple
.mask
= rmesa
->state
.stipple
.mask
;
677 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
678 &stipple
, sizeof(stipple
) );
679 UNLOCK_HARDWARE( rmesa
);
682 static void r200PolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
684 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
685 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
687 /* Can't generally do unfilled via tcl, but some good special
690 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_UNFILLED
, flag
);
691 if (rmesa
->TclFallback
) {
692 r200ChooseRenderState( ctx
);
693 r200ChooseVertexState( ctx
);
698 /* =============================================================
699 * Rendering attributes
701 * We really don't want to recalculate all this every time we bind a
702 * texture. These things shouldn't change all that often, so it makes
703 * sense to break them out of the core texture state update routines.
706 /* Examine lighting and texture state to determine if separate specular
709 static void r200UpdateSpecular( GLcontext
*ctx
)
711 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
712 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
714 R200_STATECHANGE( rmesa
, tcl
);
715 R200_STATECHANGE( rmesa
, vtx
);
717 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] &= ~(3<<R200_VTX_COLOR_0_SHIFT
);
718 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] &= ~(3<<R200_VTX_COLOR_1_SHIFT
);
719 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] &= ~R200_OUTPUT_COLOR_0
;
720 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] &= ~R200_OUTPUT_COLOR_1
;
721 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_LIGHTING_ENABLE
;
723 p
&= ~R200_SPECULAR_ENABLE
;
725 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_DIFFUSE_SPECULAR_COMBINE
;
728 if (ctx
->Light
.Enabled
&&
729 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
730 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
731 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
732 (R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
));
733 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_0
;
734 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_1
;
735 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LIGHTING_ENABLE
;
736 p
|= R200_SPECULAR_ENABLE
;
737 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &=
738 ~R200_DIFFUSE_SPECULAR_COMBINE
;
740 else if (ctx
->Light
.Enabled
) {
741 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
742 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
));
743 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_0
;
744 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LIGHTING_ENABLE
;
745 } else if (ctx
->Fog
.ColorSumEnabled
) {
746 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
747 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
748 (R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
));
749 p
|= R200_SPECULAR_ENABLE
;
751 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
752 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
));
755 if (ctx
->Fog
.Enabled
) {
756 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_0
] |=
757 ((R200_VTX_FP_RGBA
<< R200_VTX_COLOR_1_SHIFT
));
758 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] |= R200_OUTPUT_COLOR_1
;
761 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
762 R200_STATECHANGE( rmesa
, ctx
);
763 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
766 /* Update vertex/render formats
768 if (rmesa
->TclFallback
) {
769 r200ChooseRenderState( ctx
);
770 r200ChooseVertexState( ctx
);
775 /* =============================================================
780 /* Update on colormaterial, material emmissive/ambient,
781 * lightmodel.globalambient
783 static void update_global_ambient( GLcontext
*ctx
)
785 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
786 float *fcmd
= (float *)R200_DB_STATE( glt
);
788 /* Need to do more if both emmissive & ambient are PREMULT:
789 * I believe this is not nessary when using source_material. This condition thus
790 * will never happen currently, and the function has no dependencies on materials now
792 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
] &
793 ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT
) |
794 (3 << R200_FRONT_AMBIENT_SOURCE_SHIFT
))) == 0)
796 COPY_3V( &fcmd
[GLT_RED
],
797 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
798 ACC_SCALE_3V( &fcmd
[GLT_RED
],
799 ctx
->Light
.Model
.Ambient
,
800 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
804 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
807 R200_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
810 /* Update on change to
814 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
816 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
818 /* fprintf(stderr, "%s\n", __FUNCTION__); */
821 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
822 float *fcmd
= (float *)R200_DB_STATE( lit
[p
] );
824 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
825 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
826 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
828 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
832 static void r200ColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
834 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
835 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
];
836 light_model_ctl1
&= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT
) |
837 (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT
) |
838 (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT
) |
839 (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT
) |
840 (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT
) |
841 (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT
) |
842 (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT
) |
843 (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT
));
845 if (ctx
->Light
.ColorMaterialEnabled
) {
846 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
848 if (mask
& MAT_BIT_FRONT_EMISSION
) {
849 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
850 R200_FRONT_EMISSIVE_SOURCE_SHIFT
);
853 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
854 R200_FRONT_EMISSIVE_SOURCE_SHIFT
);
856 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
857 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
858 R200_FRONT_AMBIENT_SOURCE_SHIFT
);
861 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
862 R200_FRONT_AMBIENT_SOURCE_SHIFT
);
864 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
865 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
866 R200_FRONT_DIFFUSE_SOURCE_SHIFT
);
869 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
870 R200_FRONT_DIFFUSE_SOURCE_SHIFT
);
872 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
873 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
874 R200_FRONT_SPECULAR_SOURCE_SHIFT
);
877 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_0
<<
878 R200_FRONT_SPECULAR_SOURCE_SHIFT
);
881 if (mask
& MAT_BIT_BACK_EMISSION
) {
882 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
883 R200_BACK_EMISSIVE_SOURCE_SHIFT
);
886 else light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
887 R200_BACK_EMISSIVE_SOURCE_SHIFT
);
889 if (mask
& MAT_BIT_BACK_AMBIENT
) {
890 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
891 R200_BACK_AMBIENT_SOURCE_SHIFT
);
893 else light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
894 R200_BACK_AMBIENT_SOURCE_SHIFT
);
896 if (mask
& MAT_BIT_BACK_DIFFUSE
) {
897 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
898 R200_BACK_DIFFUSE_SOURCE_SHIFT
);
900 else light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
901 R200_BACK_DIFFUSE_SOURCE_SHIFT
);
903 if (mask
& MAT_BIT_BACK_SPECULAR
) {
904 light_model_ctl1
|= (R200_LM1_SOURCE_VERTEX_COLOR_0
<<
905 R200_BACK_SPECULAR_SOURCE_SHIFT
);
908 light_model_ctl1
|= (R200_LM1_SOURCE_MATERIAL_1
<<
909 R200_BACK_SPECULAR_SOURCE_SHIFT
);
913 /* Default to SOURCE_MATERIAL:
916 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_EMISSIVE_SOURCE_SHIFT
) |
917 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_AMBIENT_SOURCE_SHIFT
) |
918 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_DIFFUSE_SOURCE_SHIFT
) |
919 (R200_LM1_SOURCE_MATERIAL_0
<< R200_FRONT_SPECULAR_SOURCE_SHIFT
) |
920 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_EMISSIVE_SOURCE_SHIFT
) |
921 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_AMBIENT_SOURCE_SHIFT
) |
922 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_DIFFUSE_SOURCE_SHIFT
) |
923 (R200_LM1_SOURCE_MATERIAL_1
<< R200_BACK_SPECULAR_SOURCE_SHIFT
);
926 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
]) {
927 R200_STATECHANGE( rmesa
, tcl
);
928 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_1
] = light_model_ctl1
;
934 void r200UpdateMaterial( GLcontext
*ctx
)
936 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
937 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
938 GLfloat
*fcmd
= (GLfloat
*)R200_DB_STATE( mtl
[0] );
939 GLfloat
*fcmd2
= (GLfloat
*)R200_DB_STATE( mtl
[1] );
942 /* Might be possible and faster to update everything unconditionally? */
943 if (ctx
->Light
.ColorMaterialEnabled
)
944 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
946 if (R200_DEBUG
& DEBUG_STATE
)
947 fprintf(stderr
, "%s\n", __FUNCTION__
);
949 if (mask
& MAT_BIT_FRONT_EMISSION
) {
950 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
951 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
952 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
953 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
955 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
956 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
957 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
958 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
959 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
961 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
962 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
963 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
964 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
965 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
967 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
968 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
969 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
970 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
971 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
973 if (mask
& MAT_BIT_FRONT_SHININESS
) {
974 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
977 if (mask
& MAT_BIT_BACK_EMISSION
) {
978 fcmd2
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_BACK_EMISSION
][0];
979 fcmd2
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_BACK_EMISSION
][1];
980 fcmd2
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_BACK_EMISSION
][2];
981 fcmd2
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_BACK_EMISSION
][3];
983 if (mask
& MAT_BIT_BACK_AMBIENT
) {
984 fcmd2
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][0];
985 fcmd2
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][1];
986 fcmd2
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][2];
987 fcmd2
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_BACK_AMBIENT
][3];
989 if (mask
& MAT_BIT_BACK_DIFFUSE
) {
990 fcmd2
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][0];
991 fcmd2
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][1];
992 fcmd2
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][2];
993 fcmd2
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_BACK_DIFFUSE
][3];
995 if (mask
& MAT_BIT_BACK_SPECULAR
) {
996 fcmd2
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][0];
997 fcmd2
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][1];
998 fcmd2
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][2];
999 fcmd2
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_BACK_SPECULAR
][3];
1001 if (mask
& MAT_BIT_BACK_SHININESS
) {
1002 fcmd2
[MTL_SHININESS
] = mat
[MAT_ATTRIB_BACK_SHININESS
][0];
1005 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
[0] );
1006 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
[1] );
1008 /* currently material changes cannot trigger a global ambient change, I believe this is correct
1009 update_global_ambient( ctx ); */
1014 * _MESA_NEW_NEED_EYE_COORDS
1016 * Uses derived state from mesa:
1021 * _ModelViewInvScale
1025 * which are calculated in light.c and are correct for the current
1026 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
1027 * and _MESA_NEW_NEED_EYE_COORDS.
1029 static void update_light( GLcontext
*ctx
)
1031 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1033 /* Have to check these, or have an automatic shortcircuit mechanism
1034 * to remove noop statechanges. (Or just do a better job on the
1038 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
];
1040 if (ctx
->_NeedEyeCoords
)
1041 tmp
&= ~R200_LIGHT_IN_MODELSPACE
;
1043 tmp
|= R200_LIGHT_IN_MODELSPACE
;
1045 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
])
1047 R200_STATECHANGE( rmesa
, tcl
);
1048 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] = tmp
;
1053 GLfloat
*fcmd
= (GLfloat
*)R200_DB_STATE( eye
);
1054 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1055 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1056 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1057 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1058 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1063 if (ctx
->Light
.Enabled
) {
1065 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1066 if (ctx
->Light
.Light
[p
].Enabled
) {
1067 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1068 GLfloat
*fcmd
= (GLfloat
*)R200_DB_STATE( lit
[p
] );
1070 if (l
->EyePosition
[3] == 0.0) {
1071 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1072 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1073 fcmd
[LIT_POSITION_W
] = 0;
1074 fcmd
[LIT_DIRECTION_W
] = 0;
1076 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1077 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1078 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1079 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1080 fcmd
[LIT_DIRECTION_W
] = 0;
1083 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1089 static void r200Lightfv( GLcontext
*ctx
, GLenum light
,
1090 GLenum pname
, const GLfloat
*params
)
1092 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1093 GLint p
= light
- GL_LIGHT0
;
1094 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1095 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1102 update_light_colors( ctx
, p
);
1105 case GL_SPOT_DIRECTION
:
1106 /* picked up in update_light */
1110 /* positions picked up in update_light, but can do flag here */
1111 GLuint flag
= (p
&1)? R200_LIGHT_1_IS_LOCAL
: R200_LIGHT_0_IS_LOCAL
;
1112 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1114 R200_STATECHANGE(rmesa
, tcl
);
1115 if (l
->EyePosition
[3] != 0.0F
)
1116 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1118 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1122 case GL_SPOT_EXPONENT
:
1123 R200_STATECHANGE(rmesa
, lit
[p
]);
1124 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1127 case GL_SPOT_CUTOFF
: {
1128 GLuint flag
= (p
&1) ? R200_LIGHT_1_IS_SPOT
: R200_LIGHT_0_IS_SPOT
;
1129 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1131 R200_STATECHANGE(rmesa
, lit
[p
]);
1132 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1134 R200_STATECHANGE(rmesa
, tcl
);
1135 if (l
->SpotCutoff
!= 180.0F
)
1136 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1138 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1143 case GL_CONSTANT_ATTENUATION
:
1144 R200_STATECHANGE(rmesa
, lit
[p
]);
1145 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1146 if ( params
[0] == 0.0 )
1147 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1149 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1151 case GL_LINEAR_ATTENUATION
:
1152 R200_STATECHANGE(rmesa
, lit
[p
]);
1153 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1155 case GL_QUADRATIC_ATTENUATION
:
1156 R200_STATECHANGE(rmesa
, lit
[p
]);
1157 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1163 /* Set RANGE_ATTEN only when needed */
1166 case GL_CONSTANT_ATTENUATION
:
1167 case GL_LINEAR_ATTENUATION
:
1168 case GL_QUADRATIC_ATTENUATION
: {
1169 GLuint
*icmd
= (GLuint
*)R200_DB_STATE( tcl
);
1170 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1171 GLuint atten_flag
= ( p
&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN
1172 : R200_LIGHT_0_ENABLE_RANGE_ATTEN
;
1173 GLuint atten_const_flag
= ( p
&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN
1174 : R200_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1176 if ( l
->EyePosition
[3] == 0.0F
||
1177 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1178 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1179 /* Disable attenuation */
1180 icmd
[idx
] &= ~atten_flag
;
1182 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1183 /* Enable only constant portion of attenuation calculation */
1184 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1186 /* Enable full attenuation calculation */
1187 icmd
[idx
] &= ~atten_const_flag
;
1188 icmd
[idx
] |= atten_flag
;
1192 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1203 static void r200LightModelfv( GLcontext
*ctx
, GLenum pname
,
1204 const GLfloat
*param
)
1206 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1209 case GL_LIGHT_MODEL_AMBIENT
:
1210 update_global_ambient( ctx
);
1213 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1214 R200_STATECHANGE( rmesa
, tcl
);
1215 if (ctx
->Light
.Model
.LocalViewer
)
1216 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LOCAL_VIEWER
;
1218 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_LOCAL_VIEWER
;
1221 case GL_LIGHT_MODEL_TWO_SIDE
:
1222 R200_STATECHANGE( rmesa
, tcl
);
1223 if (ctx
->Light
.Model
.TwoSide
)
1224 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_LIGHT_TWOSIDE
;
1226 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~(R200_LIGHT_TWOSIDE
);
1227 if (rmesa
->TclFallback
) {
1228 r200ChooseRenderState( ctx
);
1229 r200ChooseVertexState( ctx
);
1233 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1234 r200UpdateSpecular(ctx
);
1242 static void r200ShadeModel( GLcontext
*ctx
, GLenum mode
)
1244 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1245 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1247 s
&= ~(R200_DIFFUSE_SHADE_MASK
|
1248 R200_ALPHA_SHADE_MASK
|
1249 R200_SPECULAR_SHADE_MASK
|
1250 R200_FOG_SHADE_MASK
);
1254 s
|= (R200_DIFFUSE_SHADE_FLAT
|
1255 R200_ALPHA_SHADE_FLAT
|
1256 R200_SPECULAR_SHADE_FLAT
|
1257 R200_FOG_SHADE_FLAT
);
1260 s
|= (R200_DIFFUSE_SHADE_GOURAUD
|
1261 R200_ALPHA_SHADE_GOURAUD
|
1262 R200_SPECULAR_SHADE_GOURAUD
|
1263 R200_FOG_SHADE_GOURAUD
);
1269 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1270 R200_STATECHANGE( rmesa
, set
);
1271 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1276 /* =============================================================
1280 static void r200ClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1282 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1283 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1284 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1286 R200_STATECHANGE( rmesa
, ucp
[p
] );
1287 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1288 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1289 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1290 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1293 static void r200UpdateClipPlanes( GLcontext
*ctx
)
1295 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1298 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1299 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1300 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1302 R200_STATECHANGE( rmesa
, ucp
[p
] );
1303 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1304 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1305 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1306 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1312 /* =============================================================
1316 static void r200StencilFunc( GLcontext
*ctx
, GLenum func
,
1317 GLint ref
, GLuint mask
)
1319 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1320 GLuint refmask
= ((ctx
->Stencil
.Ref
[0] << R200_STENCIL_REF_SHIFT
) |
1321 (ctx
->Stencil
.ValueMask
[0] << R200_STENCIL_MASK_SHIFT
));
1323 R200_STATECHANGE( rmesa
, ctx
);
1324 R200_STATECHANGE( rmesa
, msk
);
1326 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~R200_STENCIL_TEST_MASK
;
1327 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(R200_STENCIL_REF_MASK
|
1328 R200_STENCIL_VALUE_MASK
);
1330 switch ( ctx
->Stencil
.Function
[0] ) {
1332 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_NEVER
;
1335 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_LESS
;
1338 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_EQUAL
;
1341 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_LEQUAL
;
1344 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_GREATER
;
1347 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_NEQUAL
;
1350 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_GEQUAL
;
1353 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_TEST_ALWAYS
;
1357 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1360 static void r200StencilMask( GLcontext
*ctx
, GLuint mask
)
1362 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1364 R200_STATECHANGE( rmesa
, msk
);
1365 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~R200_STENCIL_WRITE_MASK
;
1366 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1367 (ctx
->Stencil
.WriteMask
[0] << R200_STENCIL_WRITEMASK_SHIFT
);
1370 static void r200StencilOp( GLcontext
*ctx
, GLenum fail
,
1371 GLenum zfail
, GLenum zpass
)
1373 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1375 R200_STATECHANGE( rmesa
, ctx
);
1376 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(R200_STENCIL_FAIL_MASK
|
1377 R200_STENCIL_ZFAIL_MASK
|
1378 R200_STENCIL_ZPASS_MASK
);
1380 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1382 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_KEEP
;
1385 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_ZERO
;
1388 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_REPLACE
;
1391 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_INC
;
1394 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_DEC
;
1396 case GL_INCR_WRAP_EXT
:
1397 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_INC_WRAP
;
1399 case GL_DECR_WRAP_EXT
:
1400 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_DEC_WRAP
;
1403 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_FAIL_INVERT
;
1407 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1409 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_KEEP
;
1412 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_ZERO
;
1415 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_REPLACE
;
1418 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_INC
;
1421 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_DEC
;
1423 case GL_INCR_WRAP_EXT
:
1424 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_INC_WRAP
;
1426 case GL_DECR_WRAP_EXT
:
1427 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_DEC_WRAP
;
1430 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZFAIL_INVERT
;
1434 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1436 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_KEEP
;
1439 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_ZERO
;
1442 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_REPLACE
;
1445 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_INC
;
1448 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_DEC
;
1450 case GL_INCR_WRAP_EXT
:
1451 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_INC_WRAP
;
1453 case GL_DECR_WRAP_EXT
:
1454 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_DEC_WRAP
;
1457 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= R200_STENCIL_ZPASS_INVERT
;
1462 static void r200ClearStencil( GLcontext
*ctx
, GLint s
)
1464 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1466 rmesa
->state
.stencil
.clear
=
1467 ((GLuint
) ctx
->Stencil
.Clear
|
1468 (0xff << R200_STENCIL_MASK_SHIFT
) |
1469 (ctx
->Stencil
.WriteMask
[0] << R200_STENCIL_WRITEMASK_SHIFT
));
1473 /* =============================================================
1474 * Window position and viewport transformation
1478 * To correctly position primitives:
1480 #define SUBPIXEL_X 0.125
1481 #define SUBPIXEL_Y 0.125
1483 void r200UpdateWindow( GLcontext
*ctx
)
1485 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1486 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1487 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1488 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1489 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1491 GLfloat sx
= v
[MAT_SX
];
1492 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1493 GLfloat sy
= - v
[MAT_SY
];
1494 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1495 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1496 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1498 R200_FIREVERTICES( rmesa
);
1499 R200_STATECHANGE( rmesa
, vpt
);
1501 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = *(GLuint
*)&sx
;
1502 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1503 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = *(GLuint
*)&sy
;
1504 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1505 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = *(GLuint
*)&sz
;
1506 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = *(GLuint
*)&tz
;
1511 static void r200Viewport( GLcontext
*ctx
, GLint x
, GLint y
,
1512 GLsizei width
, GLsizei height
)
1514 /* Don't pipeline viewport changes, conflict with window offset
1515 * setting below. Could apply deltas to rescue pipelined viewport
1516 * values, or keep the originals hanging around.
1518 R200_FIREVERTICES( R200_CONTEXT(ctx
) );
1519 r200UpdateWindow( ctx
);
1522 static void r200DepthRange( GLcontext
*ctx
, GLclampd nearval
,
1525 r200UpdateWindow( ctx
);
1528 void r200UpdateViewportOffset( GLcontext
*ctx
)
1530 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1531 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1532 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1533 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1534 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1536 GLfloat tx
= v
[MAT_TX
] + xoffset
;
1537 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
;
1539 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != *(GLuint
*)&tx
||
1540 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != *(GLuint
*)&ty
)
1542 /* Note: this should also modify whatever data the context reset
1545 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1546 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1548 /* update polygon stipple x/y screen offset */
1551 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1553 m
&= ~(R200_STIPPLE_X_OFFSET_MASK
|
1554 R200_STIPPLE_Y_OFFSET_MASK
);
1556 /* add magic offsets, then invert */
1557 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & R200_STIPPLE_COORD_MASK
);
1558 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1559 & R200_STIPPLE_COORD_MASK
);
1561 m
|= ((stx
<< R200_STIPPLE_X_OFFSET_SHIFT
) |
1562 (sty
<< R200_STIPPLE_Y_OFFSET_SHIFT
));
1564 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1565 R200_STATECHANGE( rmesa
, msc
);
1566 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1571 r200UpdateScissor( ctx
);
1576 /* =============================================================
1580 static void r200ClearColor( GLcontext
*ctx
, const GLfloat c
[4] )
1582 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1584 CLAMPED_FLOAT_TO_UBYTE(color
[0], c
[0]);
1585 CLAMPED_FLOAT_TO_UBYTE(color
[1], c
[1]);
1586 CLAMPED_FLOAT_TO_UBYTE(color
[2], c
[2]);
1587 CLAMPED_FLOAT_TO_UBYTE(color
[3], c
[3]);
1588 rmesa
->state
.color
.clear
= r200PackColor( rmesa
->r200Screen
->cpp
,
1590 color
[2], color
[3] );
1594 static void r200RenderMode( GLcontext
*ctx
, GLenum mode
)
1596 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1597 FALLBACK( rmesa
, R200_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1601 static GLuint r200_rop_tab
[] = {
1604 R200_ROP_AND_REVERSE
,
1606 R200_ROP_AND_INVERTED
,
1613 R200_ROP_OR_REVERSE
,
1614 R200_ROP_COPY_INVERTED
,
1615 R200_ROP_OR_INVERTED
,
1620 static void r200LogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1622 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1623 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1627 R200_STATECHANGE( rmesa
, msk
);
1628 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = r200_rop_tab
[rop
];
1632 void r200SetCliprects( r200ContextPtr rmesa
, GLenum mode
)
1634 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1638 rmesa
->numClipRects
= dPriv
->numClipRects
;
1639 rmesa
->pClipRects
= dPriv
->pClipRects
;
1642 /* Can't ignore 2d windows if we are page flipping.
1644 if ( dPriv
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1645 rmesa
->numClipRects
= dPriv
->numClipRects
;
1646 rmesa
->pClipRects
= dPriv
->pClipRects
;
1649 rmesa
->numClipRects
= dPriv
->numBackClipRects
;
1650 rmesa
->pClipRects
= dPriv
->pBackClipRects
;
1654 fprintf(stderr
, "bad mode in r200SetCliprects\n");
1658 if (rmesa
->state
.scissor
.enabled
)
1659 r200RecalcScissorRects( rmesa
);
1663 static void r200DrawBuffer( GLcontext
*ctx
, GLenum mode
)
1665 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1667 if (R200_DEBUG
& DEBUG_DRI
)
1668 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1669 _mesa_lookup_enum_by_nr( mode
));
1671 R200_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1674 * _DrawDestMask is easier to cope with than <mode>.
1676 switch ( ctx
->Color
._DrawDestMask
) {
1677 case DD_FRONT_LEFT_BIT
:
1678 FALLBACK( rmesa
, R200_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1679 r200SetCliprects( rmesa
, GL_FRONT_LEFT
);
1681 case DD_BACK_LEFT_BIT
:
1682 FALLBACK( rmesa
, R200_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1683 r200SetCliprects( rmesa
, GL_BACK_LEFT
);
1686 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
1687 FALLBACK( rmesa
, R200_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1691 /* We want to update the s/w rast state too so that r200SetBuffer()
1694 _swrast_DrawBuffer(ctx
, mode
);
1696 R200_STATECHANGE( rmesa
, ctx
);
1697 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
] = ((rmesa
->state
.color
.drawOffset
+
1698 rmesa
->r200Screen
->fbLocation
)
1699 & R200_COLOROFFSET_MASK
);
1700 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = rmesa
->state
.color
.drawPitch
;
1704 static void r200ReadBuffer( GLcontext
*ctx
, GLenum mode
)
1706 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1709 /* =============================================================
1710 * State enable/disable
1713 static void r200Enable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1715 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1718 if ( R200_DEBUG
& DEBUG_STATE
)
1719 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1720 _mesa_lookup_enum_by_nr( cap
),
1721 state
? "GL_TRUE" : "GL_FALSE" );
1724 /* Fast track this one...
1732 R200_STATECHANGE( rmesa
, ctx
);
1734 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_ALPHA_TEST_ENABLE
;
1736 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_ALPHA_TEST_ENABLE
;
1741 R200_STATECHANGE( rmesa
, ctx
);
1743 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_ALPHA_BLEND_ENABLE
;
1745 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_ALPHA_BLEND_ENABLE
;
1747 if ( ctx
->Color
._LogicOpEnabled
) {
1748 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_ROP_ENABLE
;
1750 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_ROP_ENABLE
;
1754 case GL_CLIP_PLANE0
:
1755 case GL_CLIP_PLANE1
:
1756 case GL_CLIP_PLANE2
:
1757 case GL_CLIP_PLANE3
:
1758 case GL_CLIP_PLANE4
:
1759 case GL_CLIP_PLANE5
:
1760 p
= cap
-GL_CLIP_PLANE0
;
1761 R200_STATECHANGE( rmesa
, tcl
);
1763 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (R200_UCP_ENABLE_0
<<p
);
1764 r200ClipPlane( ctx
, cap
, NULL
);
1767 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(R200_UCP_ENABLE_0
<<p
);
1771 case GL_COLOR_MATERIAL
:
1772 r200ColorMaterial( ctx
, 0, 0 );
1773 r200UpdateMaterial( ctx
);
1777 r200CullFace( ctx
, 0 );
1781 R200_STATECHANGE(rmesa
, ctx
);
1783 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_Z_ENABLE
;
1785 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_Z_ENABLE
;
1790 R200_STATECHANGE(rmesa
, ctx
);
1792 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_DITHER_ENABLE
;
1793 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1795 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_DITHER_ENABLE
;
1796 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1801 R200_STATECHANGE(rmesa
, ctx
);
1803 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_FOG_ENABLE
;
1804 r200Fogfv( ctx
, GL_FOG_MODE
, 0 );
1806 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_FOG_ENABLE
;
1807 R200_STATECHANGE(rmesa
, tcl
);
1808 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~R200_TCL_FOG_MASK
;
1810 r200UpdateSpecular( ctx
); /* for PK_SPEC */
1811 if (rmesa
->TclFallback
)
1812 r200ChooseVertexState( ctx
);
1813 _mesa_allow_light_in_model( ctx
, !state
);
1824 R200_STATECHANGE(rmesa
, tcl
);
1825 p
= cap
- GL_LIGHT0
;
1827 flag
= (R200_LIGHT_1_ENABLE
|
1828 R200_LIGHT_1_ENABLE_AMBIENT
|
1829 R200_LIGHT_1_ENABLE_SPECULAR
);
1831 flag
= (R200_LIGHT_0_ENABLE
|
1832 R200_LIGHT_0_ENABLE_AMBIENT
|
1833 R200_LIGHT_0_ENABLE_SPECULAR
);
1836 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1838 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1842 update_light_colors( ctx
, p
);
1846 r200UpdateSpecular(ctx
);
1849 case GL_LINE_SMOOTH
:
1850 R200_STATECHANGE( rmesa
, ctx
);
1852 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_ANTI_ALIAS_LINE
;
1854 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_ANTI_ALIAS_LINE
;
1858 case GL_LINE_STIPPLE
:
1859 R200_STATECHANGE( rmesa
, set
);
1861 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] |= R200_PATTERN_ENABLE
;
1863 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] &= ~R200_PATTERN_ENABLE
;
1867 case GL_COLOR_LOGIC_OP
:
1868 R200_STATECHANGE( rmesa
, ctx
);
1869 if ( ctx
->Color
._LogicOpEnabled
) {
1870 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_ROP_ENABLE
;
1872 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_ROP_ENABLE
;
1877 R200_STATECHANGE( rmesa
, tcl
);
1879 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_NORMALIZE_NORMALS
;
1881 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_NORMALIZE_NORMALS
;
1885 /* Pointsize registers on r200 don't seem to do anything. Maybe
1886 * have to pass pointsizes as vertex parameters? In any case,
1887 * setting pointmin == pointsizemax == 1.0, and doing nothing
1888 * for aa is enough to satisfy conform.
1890 case GL_POINT_SMOOTH
:
1893 /* These don't really do anything, as we don't use the 3vtx
1897 case GL_POLYGON_OFFSET_POINT
:
1898 R200_STATECHANGE( rmesa
, set
);
1900 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_ZBIAS_ENABLE_POINT
;
1902 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_ZBIAS_ENABLE_POINT
;
1906 case GL_POLYGON_OFFSET_LINE
:
1907 R200_STATECHANGE( rmesa
, set
);
1909 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_ZBIAS_ENABLE_LINE
;
1911 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_ZBIAS_ENABLE_LINE
;
1916 case GL_POLYGON_OFFSET_FILL
:
1917 R200_STATECHANGE( rmesa
, set
);
1919 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= R200_ZBIAS_ENABLE_TRI
;
1921 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~R200_ZBIAS_ENABLE_TRI
;
1925 case GL_POLYGON_SMOOTH
:
1926 R200_STATECHANGE( rmesa
, ctx
);
1928 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_ANTI_ALIAS_POLY
;
1930 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~R200_ANTI_ALIAS_POLY
;
1934 case GL_POLYGON_STIPPLE
:
1935 R200_STATECHANGE(rmesa
, set
);
1937 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] |= R200_STIPPLE_ENABLE
;
1939 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] &= ~R200_STIPPLE_ENABLE
;
1943 case GL_RESCALE_NORMAL_EXT
: {
1944 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1945 R200_STATECHANGE( rmesa
, tcl
);
1947 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_RESCALE_NORMALS
;
1949 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_RESCALE_NORMALS
;
1954 case GL_SCISSOR_TEST
:
1955 R200_FIREVERTICES( rmesa
);
1956 rmesa
->state
.scissor
.enabled
= state
;
1957 r200UpdateScissor( ctx
);
1960 case GL_STENCIL_TEST
:
1961 if ( rmesa
->state
.stencil
.hwBuffer
) {
1962 R200_STATECHANGE( rmesa
, ctx
);
1964 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= R200_STENCIL_ENABLE
;
1966 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~R200_STENCIL_ENABLE
;
1969 FALLBACK( rmesa
, R200_FALLBACK_STENCIL
, state
);
1973 case GL_TEXTURE_GEN_Q
:
1974 case GL_TEXTURE_GEN_R
:
1975 case GL_TEXTURE_GEN_S
:
1976 case GL_TEXTURE_GEN_T
:
1977 /* Picked up in r200UpdateTextureState.
1979 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1982 case GL_COLOR_SUM_EXT
:
1983 r200UpdateSpecular ( ctx
);
1992 void r200LightingSpaceChange( GLcontext
*ctx
)
1994 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1997 if (R200_DEBUG
& DEBUG_STATE
)
1998 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1999 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
]);
2001 if (ctx
->_NeedEyeCoords
)
2002 tmp
= ctx
->Transform
.RescaleNormals
;
2004 tmp
= !ctx
->Transform
.RescaleNormals
;
2006 R200_STATECHANGE( rmesa
, tcl
);
2008 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] |= R200_RESCALE_NORMALS
;
2010 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
] &= ~R200_RESCALE_NORMALS
;
2013 if (R200_DEBUG
& DEBUG_STATE
)
2014 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2015 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL_0
]);
2018 /* =============================================================
2019 * Deferred state management - matrices, textures, other?
2025 static void upload_matrix( r200ContextPtr rmesa
, GLfloat
*src
, int idx
)
2027 float *dest
= ((float *)R200_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2031 for (i
= 0 ; i
< 4 ; i
++) {
2035 *dest
++ = src
[i
+12];
2038 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2041 static void upload_matrix_t( r200ContextPtr rmesa
, const GLfloat
*src
, int idx
)
2043 float *dest
= ((float *)R200_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2044 memcpy(dest
, src
, 16*sizeof(float));
2045 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2049 static void update_texturematrix( GLcontext
*ctx
)
2051 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
2052 GLuint tpc
= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_0
];
2053 GLuint compsel
= rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
];
2056 if (R200_DEBUG
& DEBUG_STATE
)
2057 fprintf(stderr
, "%s before COMPSEL: %x\n", __FUNCTION__
,
2058 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
]);
2060 rmesa
->TexMatEnabled
= 0;
2061 rmesa
->TexMatCompSel
= 0;
2063 for (unit
= 0 ; unit
< 2; unit
++) {
2064 if (!ctx
->Texture
.Unit
[unit
]._ReallyEnabled
)
2067 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2068 rmesa
->TexMatEnabled
|= (R200_TEXGEN_TEXMAT_0_ENABLE
|
2069 R200_TEXMAT_0_ENABLE
) << unit
;
2071 rmesa
->TexMatCompSel
|= R200_OUTPUT_TEX_0
<< unit
;
2073 if (rmesa
->TexGenEnabled
& (R200_TEXMAT_0_ENABLE
<< unit
)) {
2074 /* Need to preconcatenate any active texgen
2075 * obj/eyeplane matrices:
2077 _math_matrix_mul_matrix( &rmesa
->tmpmat
,
2078 &rmesa
->TexGenMatrix
[unit
],
2079 ctx
->TextureMatrixStack
[unit
].Top
);
2080 upload_matrix( rmesa
, rmesa
->tmpmat
.m
, R200_MTX_TEX0
+unit
);
2083 upload_matrix( rmesa
, ctx
->TextureMatrixStack
[unit
].Top
->m
,
2084 R200_MTX_TEX0
+unit
);
2087 else if (rmesa
->TexGenEnabled
& (R200_TEXMAT_0_ENABLE
<< unit
)) {
2088 upload_matrix( rmesa
, rmesa
->TexGenMatrix
[unit
].m
,
2089 R200_MTX_TEX0
+unit
);
2093 tpc
= (rmesa
->TexMatEnabled
| rmesa
->TexGenEnabled
);
2094 if (tpc
!= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_0
] ||
2095 rmesa
->TexGenInputs
!= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
]) {
2096 R200_STATECHANGE(rmesa
, tcg
);
2097 rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_0
] = tpc
;
2098 rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
] = rmesa
->TexGenInputs
;
2101 compsel
&= ~R200_OUTPUT_TEX_MASK
;
2102 compsel
|= rmesa
->TexMatCompSel
| rmesa
->TexGenCompSel
;
2103 if (compsel
!= rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
]) {
2104 R200_STATECHANGE(rmesa
, vtx
);
2105 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_COMPSEL
] = compsel
;
2111 void r200ValidateState( GLcontext
*ctx
)
2113 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
2114 GLuint new_state
= rmesa
->NewGLState
;
2116 if (new_state
& _NEW_TEXTURE
) {
2117 r200UpdateTextureState( ctx
);
2118 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2121 /* Need an event driven matrix update?
2123 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2124 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, R200_MTX_MVP
);
2126 /* Need these for lighting (shouldn't upload otherwise)
2128 if (new_state
& (_NEW_MODELVIEW
)) {
2129 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, R200_MTX_MV
);
2130 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, R200_MTX_IMV
);
2133 /* Does this need to be triggered on eg. modelview for
2134 * texgen-derived objplane/eyeplane matrices?
2136 if (new_state
& (_NEW_TEXTURE
|_NEW_TEXTURE_MATRIX
)) {
2137 update_texturematrix( ctx
);
2140 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2141 update_light( ctx
);
2144 /* emit all active clip planes if projection matrix changes.
2146 if (new_state
& (_NEW_PROJECTION
)) {
2147 if (ctx
->Transform
.ClipPlanesEnabled
)
2148 r200UpdateClipPlanes( ctx
);
2152 rmesa
->NewGLState
= 0;
2156 static void r200InvalidateState( GLcontext
*ctx
, GLuint new_state
)
2158 _swrast_InvalidateState( ctx
, new_state
);
2159 _swsetup_InvalidateState( ctx
, new_state
);
2160 _ac_InvalidateState( ctx
, new_state
);
2161 _tnl_InvalidateState( ctx
, new_state
);
2162 _ae_invalidate_state( ctx
, new_state
);
2163 R200_CONTEXT(ctx
)->NewGLState
|= new_state
;
2164 r200VtxfmtInvalidate( ctx
);
2167 /* A hack. The r200 can actually cope just fine with materials
2168 * between begin/ends, so fix this. But how ?
2170 static GLboolean
check_material( GLcontext
*ctx
)
2172 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2175 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2176 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2178 if (tnl
->vb
.AttribPtr
[i
] &&
2179 tnl
->vb
.AttribPtr
[i
]->stride
)
2185 static void r200WrapRunPipeline( GLcontext
*ctx
)
2187 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
2188 GLboolean has_material
;
2191 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2195 if (rmesa
->NewGLState
)
2196 r200ValidateState( ctx
);
2198 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2201 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2204 /* Run the pipeline.
2206 _tnl_run_pipeline( ctx
);
2209 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2214 /* Initialize the driver's state functions.
2216 void r200InitStateFuncs( struct dd_function_table
*functions
)
2218 functions
->UpdateState
= r200InvalidateState
;
2219 functions
->LightingSpaceChange
= r200LightingSpaceChange
;
2221 functions
->DrawBuffer
= r200DrawBuffer
;
2222 functions
->ReadBuffer
= r200ReadBuffer
;
2224 functions
->AlphaFunc
= r200AlphaFunc
;
2225 functions
->BlendEquationSeparate
= r200BlendEquationSeparate
;
2226 functions
->BlendFuncSeparate
= r200BlendFuncSeparate
;
2227 functions
->ClearColor
= r200ClearColor
;
2228 functions
->ClearDepth
= NULL
;
2229 functions
->ClearIndex
= NULL
;
2230 functions
->ClearStencil
= r200ClearStencil
;
2231 functions
->ClipPlane
= r200ClipPlane
;
2232 functions
->ColorMask
= r200ColorMask
;
2233 functions
->CullFace
= r200CullFace
;
2234 functions
->DepthFunc
= r200DepthFunc
;
2235 functions
->DepthMask
= r200DepthMask
;
2236 functions
->DepthRange
= r200DepthRange
;
2237 functions
->Enable
= r200Enable
;
2238 functions
->Fogfv
= r200Fogfv
;
2239 functions
->FrontFace
= r200FrontFace
;
2240 functions
->Hint
= NULL
;
2241 functions
->IndexMask
= NULL
;
2242 functions
->LightModelfv
= r200LightModelfv
;
2243 functions
->Lightfv
= r200Lightfv
;
2244 functions
->LineStipple
= r200LineStipple
;
2245 functions
->LineWidth
= r200LineWidth
;
2246 functions
->LogicOpcode
= r200LogicOpCode
;
2247 functions
->PolygonMode
= r200PolygonMode
;
2248 functions
->PolygonOffset
= r200PolygonOffset
;
2249 functions
->PolygonStipple
= r200PolygonStipple
;
2250 functions
->PointSize
= r200PointSize
;
2251 functions
->RenderMode
= r200RenderMode
;
2252 functions
->Scissor
= r200Scissor
;
2253 functions
->ShadeModel
= r200ShadeModel
;
2254 functions
->StencilFunc
= r200StencilFunc
;
2255 functions
->StencilMask
= r200StencilMask
;
2256 functions
->StencilOp
= r200StencilOp
;
2257 functions
->Viewport
= r200Viewport
;
2259 /* Swrast hooks for imaging extensions:
2261 functions
->CopyColorTable
= _swrast_CopyColorTable
;
2262 functions
->CopyColorSubTable
= _swrast_CopyColorSubTable
;
2263 functions
->CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
2264 functions
->CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
2268 void r200InitTnlFuncs( GLcontext
*ctx
)
2270 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= r200UpdateMaterial
;
2271 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= r200WrapRunPipeline
;