1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.8 2002/12/16 16:18:58 dawes Exp $ */
2 /**************************************************************************
4 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Gareth Hughes <gareth@valinux.com>
33 * Keith Whitwell <keith@tungstengraphics.com>
38 #include "api_arrayelt.h"
45 #include "array_cache/acache.h"
47 #include "tnl/t_pipeline.h"
48 #include "main/light.h"
49 #include "swrast_setup/swrast_setup.h"
51 #include "radeon_context.h"
52 #include "radeon_ioctl.h"
53 #include "radeon_state.h"
54 #include "radeon_tcl.h"
55 #include "radeon_tex.h"
56 #include "radeon_swtcl.h"
57 #include "radeon_vtxfmt.h"
58 #include "drirenderbuffer.h"
60 /* =============================================================
64 static void radeonAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
66 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
67 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
70 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
72 RADEON_STATECHANGE( rmesa
, ctx
);
74 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
75 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
79 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
82 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
85 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
88 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
91 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
94 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
97 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
100 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
104 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
107 static void radeonBlendEquationSeparate( GLcontext
*ctx
,
108 GLenum modeRGB
, GLenum modeA
)
110 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
111 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
112 GLboolean fallback
= GL_FALSE
;
114 assert( modeRGB
== modeA
);
119 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
122 case GL_FUNC_SUBTRACT
:
123 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
127 if (ctx
->Color
.BlendEnabled
)
130 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
134 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
136 RADEON_STATECHANGE( rmesa
, ctx
);
137 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
138 if ( ctx
->Color
._LogicOpEnabled
) {
139 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
141 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
146 static void radeonBlendFuncSeparate( GLcontext
*ctx
,
147 GLenum sfactorRGB
, GLenum dfactorRGB
,
148 GLenum sfactorA
, GLenum dfactorA
)
150 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
151 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
152 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
153 GLboolean fallback
= GL_FALSE
;
155 switch ( ctx
->Color
.BlendSrcRGB
) {
157 b
|= RADEON_SRC_BLEND_GL_ZERO
;
160 b
|= RADEON_SRC_BLEND_GL_ONE
;
163 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
165 case GL_ONE_MINUS_DST_COLOR
:
166 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
169 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
171 case GL_ONE_MINUS_SRC_COLOR
:
172 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
175 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
177 case GL_ONE_MINUS_SRC_ALPHA
:
178 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
181 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
183 case GL_ONE_MINUS_DST_ALPHA
:
184 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
186 case GL_SRC_ALPHA_SATURATE
:
187 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
189 case GL_CONSTANT_COLOR
:
190 case GL_ONE_MINUS_CONSTANT_COLOR
:
191 case GL_CONSTANT_ALPHA
:
192 case GL_ONE_MINUS_CONSTANT_ALPHA
:
193 if (ctx
->Color
.BlendEnabled
)
196 b
|= RADEON_SRC_BLEND_GL_ONE
;
202 switch ( ctx
->Color
.BlendDstRGB
) {
204 b
|= RADEON_DST_BLEND_GL_ZERO
;
207 b
|= RADEON_DST_BLEND_GL_ONE
;
210 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
212 case GL_ONE_MINUS_SRC_COLOR
:
213 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
216 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
218 case GL_ONE_MINUS_SRC_ALPHA
:
219 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
222 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
224 case GL_ONE_MINUS_DST_COLOR
:
225 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
228 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
230 case GL_ONE_MINUS_DST_ALPHA
:
231 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
233 case GL_CONSTANT_COLOR
:
234 case GL_ONE_MINUS_CONSTANT_COLOR
:
235 case GL_CONSTANT_ALPHA
:
236 case GL_ONE_MINUS_CONSTANT_ALPHA
:
237 if (ctx
->Color
.BlendEnabled
)
240 b
|= RADEON_DST_BLEND_GL_ZERO
;
246 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
248 RADEON_STATECHANGE( rmesa
, ctx
);
249 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
254 /* =============================================================
258 static void radeonDepthFunc( GLcontext
*ctx
, GLenum func
)
260 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
262 RADEON_STATECHANGE( rmesa
, ctx
);
263 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
265 switch ( ctx
->Depth
.Func
) {
267 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
294 static void radeonDepthMask( GLcontext
*ctx
, GLboolean flag
)
296 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
297 RADEON_STATECHANGE( rmesa
, ctx
);
299 if ( ctx
->Depth
.Mask
) {
300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
306 static void radeonClearDepth( GLcontext
*ctx
, GLclampd d
)
308 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
309 GLuint format
= (rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &
310 RADEON_DEPTH_FORMAT_MASK
);
313 case RADEON_DEPTH_FORMAT_16BIT_INT_Z
:
314 rmesa
->state
.depth
.clear
= d
* 0x0000ffff;
316 case RADEON_DEPTH_FORMAT_24BIT_INT_Z
:
317 rmesa
->state
.depth
.clear
= d
* 0x00ffffff;
323 /* =============================================================
328 static void radeonFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
330 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
331 union { int i
; float f
; } c
, d
;
334 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
335 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
339 if (!ctx
->Fog
.Enabled
)
341 RADEON_STATECHANGE(rmesa
, tcl
);
342 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
343 switch (ctx
->Fog
.Mode
) {
345 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
346 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
351 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
352 d
.f
= 1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
356 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
358 d
.f
= ctx
->Fog
.Density
;
361 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
363 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
370 switch (ctx
->Fog
.Mode
) {
373 d
.f
= ctx
->Fog
.Density
;
377 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
385 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
386 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
390 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
391 d
.f
= 1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
396 RADEON_STATECHANGE( rmesa
, ctx
);
397 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
398 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] =
399 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
401 case GL_FOG_COORDINATE_SOURCE_EXT
:
409 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
410 RADEON_STATECHANGE( rmesa
, fog
);
411 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
412 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
417 /* =============================================================
422 static GLboolean
intersect_rect( drm_clip_rect_t
*out
,
427 if ( b
->x1
> out
->x1
) out
->x1
= b
->x1
;
428 if ( b
->y1
> out
->y1
) out
->y1
= b
->y1
;
429 if ( b
->x2
< out
->x2
) out
->x2
= b
->x2
;
430 if ( b
->y2
< out
->y2
) out
->y2
= b
->y2
;
431 if ( out
->x1
>= out
->x2
) return GL_FALSE
;
432 if ( out
->y1
>= out
->y2
) return GL_FALSE
;
437 void radeonRecalcScissorRects( radeonContextPtr rmesa
)
439 drm_clip_rect_t
*out
;
442 /* Grow cliprect store?
444 if (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
445 while (rmesa
->state
.scissor
.numAllocedClipRects
< rmesa
->numClipRects
) {
446 rmesa
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
447 rmesa
->state
.scissor
.numAllocedClipRects
*= 2;
450 if (rmesa
->state
.scissor
.pClipRects
)
451 FREE(rmesa
->state
.scissor
.pClipRects
);
453 rmesa
->state
.scissor
.pClipRects
=
454 MALLOC( rmesa
->state
.scissor
.numAllocedClipRects
*
455 sizeof(drm_clip_rect_t
) );
457 if ( rmesa
->state
.scissor
.pClipRects
== NULL
) {
458 rmesa
->state
.scissor
.numAllocedClipRects
= 0;
463 out
= rmesa
->state
.scissor
.pClipRects
;
464 rmesa
->state
.scissor
.numClipRects
= 0;
466 for ( i
= 0 ; i
< rmesa
->numClipRects
; i
++ ) {
467 if ( intersect_rect( out
,
468 &rmesa
->pClipRects
[i
],
469 &rmesa
->state
.scissor
.rect
) ) {
470 rmesa
->state
.scissor
.numClipRects
++;
477 static void radeonUpdateScissor( GLcontext
*ctx
)
479 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
481 if ( rmesa
->dri
.drawable
) {
482 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
484 int x
= ctx
->Scissor
.X
;
485 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
486 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
487 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
489 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
490 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
491 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
492 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
494 radeonRecalcScissorRects( rmesa
);
499 static void radeonScissor( GLcontext
*ctx
,
500 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
502 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
504 if ( ctx
->Scissor
.Enabled
) {
505 RADEON_FIREVERTICES( rmesa
); /* don't pipeline cliprect changes */
506 radeonUpdateScissor( ctx
);
512 /* =============================================================
516 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
518 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
519 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
520 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
522 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
523 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
525 if ( ctx
->Polygon
.CullFlag
) {
526 switch ( ctx
->Polygon
.CullFaceMode
) {
528 s
&= ~RADEON_FFACE_SOLID
;
529 t
|= RADEON_CULL_FRONT
;
532 s
&= ~RADEON_BFACE_SOLID
;
533 t
|= RADEON_CULL_BACK
;
535 case GL_FRONT_AND_BACK
:
536 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
537 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
542 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
543 RADEON_STATECHANGE(rmesa
, set
);
544 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
547 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
548 RADEON_STATECHANGE(rmesa
, tcl
);
549 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
553 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
555 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
557 RADEON_STATECHANGE( rmesa
, set
);
558 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
560 RADEON_STATECHANGE( rmesa
, tcl
);
561 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
565 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
568 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
569 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
575 /* =============================================================
578 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
580 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
582 RADEON_STATECHANGE( rmesa
, lin
);
583 RADEON_STATECHANGE( rmesa
, set
);
585 /* Line width is stored in U6.4 format.
587 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
588 if ( widthf
> 1.0 ) {
589 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
591 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
595 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
597 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
599 RADEON_STATECHANGE( rmesa
, lin
);
600 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
601 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
605 /* =============================================================
608 static void radeonColorMask( GLcontext
*ctx
,
609 GLboolean r
, GLboolean g
,
610 GLboolean b
, GLboolean a
)
612 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
613 GLuint mask
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
614 ctx
->Color
.ColorMask
[RCOMP
],
615 ctx
->Color
.ColorMask
[GCOMP
],
616 ctx
->Color
.ColorMask
[BCOMP
],
617 ctx
->Color
.ColorMask
[ACOMP
] );
619 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
620 RADEON_STATECHANGE( rmesa
, msk
);
621 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
626 /* =============================================================
630 static void radeonPolygonOffset( GLcontext
*ctx
,
631 GLfloat factor
, GLfloat units
)
633 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
634 GLfloat constant
= units
* rmesa
->state
.depth
.scale
;
636 RADEON_STATECHANGE( rmesa
, zbs
);
637 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = *(GLuint
*)&factor
;
638 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = *(GLuint
*)&constant
;
641 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
643 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
645 drm_radeon_stipple_t stipple
;
647 /* Must flip pattern upside down.
649 for ( i
= 0 ; i
< 32 ; i
++ ) {
650 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
653 /* TODO: push this into cmd mechanism
655 RADEON_FIREVERTICES( rmesa
);
656 LOCK_HARDWARE( rmesa
);
658 /* FIXME: Use window x,y offsets into stipple RAM.
660 stipple
.mask
= rmesa
->state
.stipple
.mask
;
661 drmCommandWrite( rmesa
->dri
.fd
, DRM_RADEON_STIPPLE
,
662 &stipple
, sizeof(drm_radeon_stipple_t
) );
663 UNLOCK_HARDWARE( rmesa
);
666 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
668 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
669 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
671 /* Can't generally do unfilled via tcl, but some good special
674 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
675 if (rmesa
->TclFallback
) {
676 radeonChooseRenderState( ctx
);
677 radeonChooseVertexState( ctx
);
682 /* =============================================================
683 * Rendering attributes
685 * We really don't want to recalculate all this every time we bind a
686 * texture. These things shouldn't change all that often, so it makes
687 * sense to break them out of the core texture state update routines.
690 /* Examine lighting and texture state to determine if separate specular
693 static void radeonUpdateSpecular( GLcontext
*ctx
)
695 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
696 u_int32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
698 RADEON_STATECHANGE( rmesa
, tcl
);
700 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
701 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
702 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
703 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
704 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
706 p
&= ~RADEON_SPECULAR_ENABLE
;
708 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
711 if (ctx
->Light
.Enabled
&&
712 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
713 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
714 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
715 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
716 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
717 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
718 p
|= RADEON_SPECULAR_ENABLE
;
719 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
720 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
722 else if (ctx
->Light
.Enabled
) {
723 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
724 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
725 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
726 } else if (ctx
->Fog
.ColorSumEnabled
) {
727 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
728 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
729 p
|= RADEON_SPECULAR_ENABLE
;
731 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
734 if (ctx
->Fog
.Enabled
) {
735 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
736 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
738 /* Bizzare: have to leave lighting enabled to get fog.
740 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
743 if (NEED_SECONDARY_COLOR(ctx
)) {
744 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
746 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
749 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
750 RADEON_STATECHANGE( rmesa
, ctx
);
751 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
754 /* Update vertex/render formats
756 if (rmesa
->TclFallback
) {
757 radeonChooseRenderState( ctx
);
758 radeonChooseVertexState( ctx
);
763 /* =============================================================
768 /* Update on colormaterial, material emmissive/ambient,
769 * lightmodel.globalambient
771 static void update_global_ambient( GLcontext
*ctx
)
773 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
774 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
776 /* Need to do more if both emmissive & ambient are PREMULT:
777 * Hope this is not needed for MULT
779 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
780 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
781 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
783 COPY_3V( &fcmd
[GLT_RED
],
784 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
785 ACC_SCALE_3V( &fcmd
[GLT_RED
],
786 ctx
->Light
.Model
.Ambient
,
787 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
791 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
794 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
797 /* Update on change to
801 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
803 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
805 /* fprintf(stderr, "%s\n", __FUNCTION__); */
808 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
809 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
811 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
812 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
813 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
815 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
819 /* Also fallback for asym colormaterial mode in twoside lighting...
821 static void check_twoside_fallback( GLcontext
*ctx
)
823 GLboolean fallback
= GL_FALSE
;
826 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
827 if (ctx
->Light
.ColorMaterialEnabled
&&
828 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
829 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
832 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
833 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
834 ctx
->Light
.Material
.Attrib
[i
+1],
835 sizeof(GLfloat
)*4) != 0) {
842 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
846 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
848 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
849 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
851 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
852 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
853 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
854 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
856 if (ctx
->Light
.ColorMaterialEnabled
) {
857 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
859 if (mask
& MAT_BIT_FRONT_EMISSION
) {
860 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
861 RADEON_EMISSIVE_SOURCE_SHIFT
);
864 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
865 RADEON_EMISSIVE_SOURCE_SHIFT
);
868 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
869 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
870 RADEON_AMBIENT_SOURCE_SHIFT
);
873 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
874 RADEON_AMBIENT_SOURCE_SHIFT
);
877 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
878 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
879 RADEON_DIFFUSE_SOURCE_SHIFT
);
882 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
883 RADEON_DIFFUSE_SOURCE_SHIFT
);
886 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
887 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
888 RADEON_SPECULAR_SOURCE_SHIFT
);
891 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
892 RADEON_SPECULAR_SOURCE_SHIFT
);
898 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
899 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
900 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
901 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
904 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
905 RADEON_STATECHANGE( rmesa
, tcl
);
906 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
910 void radeonUpdateMaterial( GLcontext
*ctx
)
912 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
913 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
914 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
917 if (ctx
->Light
.ColorMaterialEnabled
)
918 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
920 if (RADEON_DEBUG
& DEBUG_STATE
)
921 fprintf(stderr
, "%s\n", __FUNCTION__
);
924 if (mask
& MAT_BIT_FRONT_EMISSION
) {
925 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
926 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
927 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
928 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
930 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
931 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
932 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
933 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
934 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
936 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
937 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
938 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
939 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
940 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
942 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
943 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
944 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
945 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
946 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
948 if (mask
& MAT_BIT_FRONT_SHININESS
) {
949 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
952 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
954 check_twoside_fallback( ctx
);
955 /* update_global_ambient( ctx );*/
960 * _MESA_NEW_NEED_EYE_COORDS
962 * Uses derived state from mesa:
971 * which are calculated in light.c and are correct for the current
972 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
973 * and _MESA_NEW_NEED_EYE_COORDS.
975 static void update_light( GLcontext
*ctx
)
977 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
979 /* Have to check these, or have an automatic shortcircuit mechanism
980 * to remove noop statechanges. (Or just do a better job on the
984 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
986 if (ctx
->_NeedEyeCoords
)
987 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
989 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
992 /* Leave this test disabled: (unexplained q3 lockup) (even with
995 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
997 RADEON_STATECHANGE( rmesa
, tcl
);
998 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
1003 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
1004 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
1005 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
1006 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
1007 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
1008 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
1013 if (ctx
->Light
.Enabled
) {
1015 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
1016 if (ctx
->Light
.Light
[p
].Enabled
) {
1017 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1018 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
1020 if (l
->EyePosition
[3] == 0.0) {
1021 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
1022 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
1023 fcmd
[LIT_POSITION_W
] = 0;
1024 fcmd
[LIT_DIRECTION_W
] = 0;
1026 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
1027 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
1028 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
1029 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
1030 fcmd
[LIT_DIRECTION_W
] = 0;
1033 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
1039 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
1040 GLenum pname
, const GLfloat
*params
)
1042 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1043 GLint p
= light
- GL_LIGHT0
;
1044 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
1045 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
1052 update_light_colors( ctx
, p
);
1055 case GL_SPOT_DIRECTION
:
1056 /* picked up in update_light */
1060 /* positions picked up in update_light, but can do flag here */
1062 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1064 /* FIXME: Set RANGE_ATTEN only when needed */
1066 flag
= RADEON_LIGHT_1_IS_LOCAL
;
1068 flag
= RADEON_LIGHT_0_IS_LOCAL
;
1070 RADEON_STATECHANGE(rmesa
, tcl
);
1071 if (l
->EyePosition
[3] != 0.0F
)
1072 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1074 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1078 case GL_SPOT_EXPONENT
:
1079 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1080 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1083 case GL_SPOT_CUTOFF
: {
1084 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
1085 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1087 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1088 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1090 RADEON_STATECHANGE(rmesa
, tcl
);
1091 if (l
->SpotCutoff
!= 180.0F
)
1092 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1094 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1099 case GL_CONSTANT_ATTENUATION
:
1100 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1101 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1102 if ( params
[0] == 0.0 )
1103 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1105 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1107 case GL_LINEAR_ATTENUATION
:
1108 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1109 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1111 case GL_QUADRATIC_ATTENUATION
:
1112 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1113 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1119 /* Set RANGE_ATTEN only when needed */
1122 case GL_CONSTANT_ATTENUATION
:
1123 case GL_LINEAR_ATTENUATION
:
1124 case GL_QUADRATIC_ATTENUATION
:
1126 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1127 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1128 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1129 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1130 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1131 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1133 if ( l
->EyePosition
[3] == 0.0F
||
1134 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1135 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1136 /* Disable attenuation */
1137 icmd
[idx
] &= ~atten_flag
;
1139 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1140 /* Enable only constant portion of attenuation calculation */
1141 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1143 /* Enable full attenuation calculation */
1144 icmd
[idx
] &= ~atten_const_flag
;
1145 icmd
[idx
] |= atten_flag
;
1149 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1160 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1161 const GLfloat
*param
)
1163 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1166 case GL_LIGHT_MODEL_AMBIENT
:
1167 update_global_ambient( ctx
);
1170 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1171 RADEON_STATECHANGE( rmesa
, tcl
);
1172 if (ctx
->Light
.Model
.LocalViewer
)
1173 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1175 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1178 case GL_LIGHT_MODEL_TWO_SIDE
:
1179 RADEON_STATECHANGE( rmesa
, tcl
);
1180 if (ctx
->Light
.Model
.TwoSide
)
1181 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1183 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1185 check_twoside_fallback( ctx
);
1187 if (rmesa
->TclFallback
) {
1188 radeonChooseRenderState( ctx
);
1189 radeonChooseVertexState( ctx
);
1193 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1194 radeonUpdateSpecular(ctx
);
1202 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1204 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1205 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1207 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1208 RADEON_ALPHA_SHADE_MASK
|
1209 RADEON_SPECULAR_SHADE_MASK
|
1210 RADEON_FOG_SHADE_MASK
);
1214 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1215 RADEON_ALPHA_SHADE_FLAT
|
1216 RADEON_SPECULAR_SHADE_FLAT
|
1217 RADEON_FOG_SHADE_FLAT
);
1220 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1221 RADEON_ALPHA_SHADE_GOURAUD
|
1222 RADEON_SPECULAR_SHADE_GOURAUD
|
1223 RADEON_FOG_SHADE_GOURAUD
);
1229 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1230 RADEON_STATECHANGE( rmesa
, set
);
1231 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1236 /* =============================================================
1240 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1242 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1243 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1244 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1246 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1247 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1248 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1249 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1250 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1253 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1255 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1258 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1259 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1260 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1262 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1263 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1264 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1265 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1266 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1272 /* =============================================================
1277 radeonStencilFuncSeparate( GLcontext
*ctx
, GLenum face
, GLenum func
,
1278 GLint ref
, GLuint mask
)
1280 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1281 GLuint refmask
= ((ctx
->Stencil
.Ref
[0] << RADEON_STENCIL_REF_SHIFT
) |
1282 (ctx
->Stencil
.ValueMask
[0] << RADEON_STENCIL_MASK_SHIFT
));
1284 RADEON_STATECHANGE( rmesa
, ctx
);
1285 RADEON_STATECHANGE( rmesa
, msk
);
1287 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1288 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1289 RADEON_STENCIL_VALUE_MASK
);
1291 switch ( ctx
->Stencil
.Function
[0] ) {
1293 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1296 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1299 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1305 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1308 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1311 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1314 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1318 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1322 radeonStencilMaskSeparate( GLcontext
*ctx
, GLenum face
, GLuint mask
)
1324 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1326 RADEON_STATECHANGE( rmesa
, msk
);
1327 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1328 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1329 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
);
1332 static void radeonStencilOpSeparate( GLcontext
*ctx
, GLenum face
, GLenum fail
,
1333 GLenum zfail
, GLenum zpass
)
1335 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1337 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1338 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1339 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1341 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1342 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1343 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1344 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1345 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1346 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1348 if (rmesa
->radeonScreen
->chipset
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1349 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1350 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1351 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1352 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1353 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1354 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1357 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1358 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1359 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1360 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1361 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1362 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1365 RADEON_STATECHANGE( rmesa
, ctx
);
1366 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1367 RADEON_STENCIL_ZFAIL_MASK
|
1368 RADEON_STENCIL_ZPASS_MASK
);
1370 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1372 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1375 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1378 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1381 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1384 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1387 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1390 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1393 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1397 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1399 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1402 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1405 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1408 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1411 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1414 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1417 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1420 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1424 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1426 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1429 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1432 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1435 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1438 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1441 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1444 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1447 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1452 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1454 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1456 rmesa
->state
.stencil
.clear
=
1457 ((GLuint
) ctx
->Stencil
.Clear
|
1458 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1459 (ctx
->Stencil
.WriteMask
[0] << RADEON_STENCIL_WRITEMASK_SHIFT
));
1463 /* =============================================================
1464 * Window position and viewport transformation
1468 * To correctly position primitives:
1470 #define SUBPIXEL_X 0.125
1471 #define SUBPIXEL_Y 0.125
1475 * Called when window size or position changes or viewport or depth range
1476 * state is changed. We update the hardware viewport state here.
1478 void radeonUpdateWindow( GLcontext
*ctx
)
1480 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1481 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1482 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1483 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1484 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1486 GLfloat sx
= v
[MAT_SX
];
1487 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1488 GLfloat sy
= - v
[MAT_SY
];
1489 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1490 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
1491 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
1492 RADEON_FIREVERTICES( rmesa
);
1493 RADEON_STATECHANGE( rmesa
, vpt
);
1495 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = *(GLuint
*)&sx
;
1496 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1497 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = *(GLuint
*)&sy
;
1498 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1499 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = *(GLuint
*)&sz
;
1500 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = *(GLuint
*)&tz
;
1505 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1506 GLsizei width
, GLsizei height
)
1508 /* update size of Mesa/software ancillary buffers */
1509 _mesa_ResizeBuffersMESA();
1510 /* Don't pipeline viewport changes, conflict with window offset
1511 * setting below. Could apply deltas to rescue pipelined viewport
1512 * values, or keep the originals hanging around.
1514 RADEON_FIREVERTICES( RADEON_CONTEXT(ctx
) );
1515 radeonUpdateWindow( ctx
);
1518 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1521 radeonUpdateWindow( ctx
);
1524 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1526 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1527 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1528 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1529 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1530 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1532 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1533 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1535 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != *(GLuint
*)&tx
||
1536 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != *(GLuint
*)&ty
)
1538 /* Note: this should also modify whatever data the context reset
1541 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = *(GLuint
*)&tx
;
1542 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = *(GLuint
*)&ty
;
1544 /* update polygon stipple x/y screen offset */
1547 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1549 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1550 RADEON_STIPPLE_Y_OFFSET_MASK
);
1552 /* add magic offsets, then invert */
1553 stx
= 31 - ((rmesa
->dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1554 sty
= 31 - ((rmesa
->dri
.drawable
->y
+ rmesa
->dri
.drawable
->h
- 1)
1555 & RADEON_STIPPLE_COORD_MASK
);
1557 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1558 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1560 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1561 RADEON_STATECHANGE( rmesa
, msc
);
1562 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1567 radeonUpdateScissor( ctx
);
1572 /* =============================================================
1576 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1578 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1580 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1581 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1582 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1583 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1584 rmesa
->state
.color
.clear
= radeonPackColor( rmesa
->radeonScreen
->cpp
,
1585 c
[0], c
[1], c
[2], c
[3] );
1589 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1591 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1592 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1596 static GLuint radeon_rop_tab
[] = {
1599 RADEON_ROP_AND_REVERSE
,
1601 RADEON_ROP_AND_INVERTED
,
1608 RADEON_ROP_OR_REVERSE
,
1609 RADEON_ROP_COPY_INVERTED
,
1610 RADEON_ROP_OR_INVERTED
,
1615 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1617 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1618 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1622 RADEON_STATECHANGE( rmesa
, msk
);
1623 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1628 * Set up the cliprects for either front or back-buffer drawing.
1630 void radeonSetCliprects( radeonContextPtr rmesa
)
1632 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
1634 if (rmesa
->glCtx
->DrawBuffer
->_ColorDrawBufferMask
[0]
1635 == BUFFER_BIT_BACK_LEFT
) {
1636 /* Can't ignore 2d windows if we are page flipping.
1638 if ( dPriv
->numBackClipRects
== 0 || rmesa
->doPageFlip
) {
1639 rmesa
->numClipRects
= dPriv
->numClipRects
;
1640 rmesa
->pClipRects
= dPriv
->pClipRects
;
1643 rmesa
->numClipRects
= dPriv
->numBackClipRects
;
1644 rmesa
->pClipRects
= dPriv
->pBackClipRects
;
1648 /* front buffer (or none, or multiple buffers */
1649 rmesa
->numClipRects
= dPriv
->numClipRects
;
1650 rmesa
->pClipRects
= dPriv
->pClipRects
;
1653 if (rmesa
->state
.scissor
.enabled
)
1654 radeonRecalcScissorRects( rmesa
);
1659 * Called via glDrawBuffer.
1661 static void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
1663 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1665 if (RADEON_DEBUG
& DEBUG_DRI
)
1666 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1667 _mesa_lookup_enum_by_nr( mode
));
1669 RADEON_FIREVERTICES(rmesa
); /* don't pipeline cliprect changes */
1672 * _ColorDrawBufferMask is easier to cope with than <mode>.
1673 * Check for software fallback, update cliprects.
1675 switch ( ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] ) {
1676 case BUFFER_BIT_FRONT_LEFT
:
1677 case BUFFER_BIT_BACK_LEFT
:
1678 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1681 /* 0 (GL_NONE) buffers or multiple color drawing buffers */
1682 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1686 radeonSetCliprects( rmesa
);
1688 /* We'll set the drawing engine's offset/pitch parameters later
1689 * when we update other state.
1693 static void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
1695 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1699 /* =============================================================
1700 * State enable/disable
1703 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1705 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1708 if ( RADEON_DEBUG
& DEBUG_STATE
)
1709 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1710 _mesa_lookup_enum_by_nr( cap
),
1711 state
? "GL_TRUE" : "GL_FALSE" );
1714 /* Fast track this one...
1722 RADEON_STATECHANGE( rmesa
, ctx
);
1724 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1726 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1731 RADEON_STATECHANGE( rmesa
, ctx
);
1733 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1735 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1737 if ( ctx
->Color
._LogicOpEnabled
) {
1738 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1740 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1743 /* Catch a possible fallback:
1746 ctx
->Driver
.BlendEquationSeparate( ctx
,
1747 ctx
->Color
.BlendEquationRGB
,
1748 ctx
->Color
.BlendEquationA
);
1749 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1750 ctx
->Color
.BlendDstRGB
,
1751 ctx
->Color
.BlendSrcA
,
1752 ctx
->Color
.BlendDstA
);
1755 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1756 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1760 case GL_CLIP_PLANE0
:
1761 case GL_CLIP_PLANE1
:
1762 case GL_CLIP_PLANE2
:
1763 case GL_CLIP_PLANE3
:
1764 case GL_CLIP_PLANE4
:
1765 case GL_CLIP_PLANE5
:
1766 p
= cap
-GL_CLIP_PLANE0
;
1767 RADEON_STATECHANGE( rmesa
, tcl
);
1769 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1770 radeonClipPlane( ctx
, cap
, NULL
);
1773 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1777 case GL_COLOR_MATERIAL
:
1778 radeonColorMaterial( ctx
, 0, 0 );
1779 radeonUpdateMaterial( ctx
);
1783 radeonCullFace( ctx
, 0 );
1787 RADEON_STATECHANGE(rmesa
, ctx
);
1789 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1791 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1796 RADEON_STATECHANGE(rmesa
, ctx
);
1798 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1799 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->state
.color
.roundEnable
;
1801 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1802 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->state
.color
.roundEnable
;
1807 RADEON_STATECHANGE(rmesa
, ctx
);
1809 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1810 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1812 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1813 RADEON_STATECHANGE(rmesa
, tcl
);
1814 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1816 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1817 if (rmesa
->TclFallback
)
1818 radeonChooseVertexState( ctx
);
1819 _mesa_allow_light_in_model( ctx
, !state
);
1830 RADEON_STATECHANGE(rmesa
, tcl
);
1831 p
= cap
- GL_LIGHT0
;
1833 flag
= (RADEON_LIGHT_1_ENABLE
|
1834 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1835 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1837 flag
= (RADEON_LIGHT_0_ENABLE
|
1838 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1839 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1842 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1844 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1848 update_light_colors( ctx
, p
);
1852 RADEON_STATECHANGE(rmesa
, tcl
);
1853 radeonUpdateSpecular(ctx
);
1854 check_twoside_fallback( ctx
);
1857 case GL_LINE_SMOOTH
:
1858 RADEON_STATECHANGE( rmesa
, ctx
);
1860 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1862 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1866 case GL_LINE_STIPPLE
:
1867 RADEON_STATECHANGE( rmesa
, ctx
);
1869 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1871 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1875 case GL_COLOR_LOGIC_OP
:
1876 RADEON_STATECHANGE( rmesa
, ctx
);
1877 if ( ctx
->Color
._LogicOpEnabled
) {
1878 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1880 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1885 RADEON_STATECHANGE( rmesa
, tcl
);
1887 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1889 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1893 case GL_POLYGON_OFFSET_POINT
:
1894 if (rmesa
->dri
.drmMinor
== 1) {
1895 radeonChooseRenderState( ctx
);
1898 RADEON_STATECHANGE( rmesa
, set
);
1900 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1902 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1907 case GL_POLYGON_OFFSET_LINE
:
1908 if (rmesa
->dri
.drmMinor
== 1) {
1909 radeonChooseRenderState( ctx
);
1912 RADEON_STATECHANGE( rmesa
, set
);
1914 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1916 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1921 case GL_POLYGON_OFFSET_FILL
:
1922 if (rmesa
->dri
.drmMinor
== 1) {
1923 radeonChooseRenderState( ctx
);
1926 RADEON_STATECHANGE( rmesa
, set
);
1928 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1930 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1935 case GL_POLYGON_SMOOTH
:
1936 RADEON_STATECHANGE( rmesa
, ctx
);
1938 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1940 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1944 case GL_POLYGON_STIPPLE
:
1945 RADEON_STATECHANGE(rmesa
, ctx
);
1947 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1949 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1953 case GL_RESCALE_NORMAL_EXT
: {
1954 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1955 RADEON_STATECHANGE( rmesa
, tcl
);
1957 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1959 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1964 case GL_SCISSOR_TEST
:
1965 RADEON_FIREVERTICES( rmesa
);
1966 rmesa
->state
.scissor
.enabled
= state
;
1967 radeonUpdateScissor( ctx
);
1970 case GL_STENCIL_TEST
:
1971 if ( rmesa
->state
.stencil
.hwBuffer
) {
1972 RADEON_STATECHANGE( rmesa
, ctx
);
1974 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1976 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1979 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1983 case GL_TEXTURE_GEN_Q
:
1984 case GL_TEXTURE_GEN_R
:
1985 case GL_TEXTURE_GEN_S
:
1986 case GL_TEXTURE_GEN_T
:
1987 /* Picked up in radeonUpdateTextureState.
1989 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1992 case GL_COLOR_SUM_EXT
:
1993 radeonUpdateSpecular ( ctx
);
2002 static void radeonLightingSpaceChange( GLcontext
*ctx
)
2004 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2006 RADEON_STATECHANGE( rmesa
, tcl
);
2008 if (RADEON_DEBUG
& DEBUG_STATE
)
2009 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2010 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
2012 if (ctx
->_NeedEyeCoords
)
2013 tmp
= ctx
->Transform
.RescaleNormals
;
2015 tmp
= !ctx
->Transform
.RescaleNormals
;
2018 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
2020 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
2023 if (RADEON_DEBUG
& DEBUG_STATE
)
2024 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
2025 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
2028 /* =============================================================
2029 * Deferred state management - matrices, textures, other?
2035 static void upload_matrix( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2037 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2041 for (i
= 0 ; i
< 4 ; i
++) {
2045 *dest
++ = src
[i
+12];
2048 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2051 static void upload_matrix_t( radeonContextPtr rmesa
, GLfloat
*src
, int idx
)
2053 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
2054 memcpy(dest
, src
, 16*sizeof(float));
2055 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2059 static void update_texturematrix( GLcontext
*ctx
)
2061 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
2062 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
2063 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2066 rmesa
->TexMatEnabled
= 0;
2068 for (unit
= 0 ; unit
< 2; unit
++) {
2069 if (!ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2071 else if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2072 GLuint inputshift
= RADEON_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
2074 rmesa
->TexMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2075 RADEON_TEXMAT_0_ENABLE
) << unit
;
2077 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2078 /* Need to preconcatenate any active texgen
2079 * obj/eyeplane matrices:
2081 _math_matrix_mul_matrix( &rmesa
->tmpmat
,
2082 &rmesa
->TexGenMatrix
[unit
],
2083 ctx
->TextureMatrixStack
[unit
].Top
);
2084 upload_matrix( rmesa
, rmesa
->tmpmat
.m
, TEXMAT_0
+unit
);
2087 rmesa
->TexMatEnabled
|=
2088 (RADEON_TEXGEN_INPUT_TEXCOORD_0
+unit
) << inputshift
;
2089 upload_matrix( rmesa
, ctx
->TextureMatrixStack
[unit
].Top
->m
,
2093 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2094 upload_matrix( rmesa
, rmesa
->TexGenMatrix
[unit
].m
,
2100 tpc
= (rmesa
->TexMatEnabled
| rmesa
->TexGenEnabled
);
2102 vs
&= ~((0xf << RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2103 (0xf << RADEON_TCL_TEX_1_OUTPUT_SHIFT
));
2105 if (tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
)
2106 vs
|= RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
;
2108 vs
|= RADEON_TCL_TEX_INPUT_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
;
2110 if (tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
)
2111 vs
|= RADEON_TCL_TEX_COMPUTED_TEX_1
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
;
2113 vs
|= RADEON_TCL_TEX_INPUT_TEX_1
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
;
2115 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2116 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2118 RADEON_STATECHANGE(rmesa
, tcl
);
2119 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2120 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2126 * Tell the card where to render (offset, pitch).
2127 * Effected by glDrawBuffer, etc
2130 radeonUpdateDrawBuffer(GLcontext
*ctx
)
2132 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2133 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
2134 driRenderbuffer
*drb
;
2136 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
2138 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
2140 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
2142 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
2145 /* drawing to multiple buffers, or none */
2150 assert(drb
->flippedPitch
);
2152 RADEON_STATECHANGE( rmesa
, ctx
);
2154 /* Note: we used the (possibly) page-flipped values */
2155 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
2156 = ((drb
->flippedOffset
+ rmesa
->radeonScreen
->fbLocation
)
2157 & RADEON_COLOROFFSET_MASK
);
2158 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
2159 if (rmesa
->sarea
->tiling_enabled
) {
2160 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= RADEON_COLOR_TILE_ENABLE
;
2165 void radeonValidateState( GLcontext
*ctx
)
2167 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2168 GLuint new_state
= rmesa
->NewGLState
;
2170 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2171 radeonUpdateDrawBuffer(ctx
);
2174 if (new_state
& _NEW_TEXTURE
) {
2175 radeonUpdateTextureState( ctx
);
2176 new_state
|= rmesa
->NewGLState
; /* may add TEXTURE_MATRIX */
2179 /* Need an event driven matrix update?
2181 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2182 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2184 /* Need these for lighting (shouldn't upload otherwise)
2186 if (new_state
& (_NEW_MODELVIEW
)) {
2187 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2188 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2191 /* Does this need to be triggered on eg. modelview for
2192 * texgen-derived objplane/eyeplane matrices?
2194 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2195 update_texturematrix( ctx
);
2198 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2199 update_light( ctx
);
2202 /* emit all active clip planes if projection matrix changes.
2204 if (new_state
& (_NEW_PROJECTION
)) {
2205 if (ctx
->Transform
.ClipPlanesEnabled
)
2206 radeonUpdateClipPlanes( ctx
);
2210 rmesa
->NewGLState
= 0;
2214 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2216 _swrast_InvalidateState( ctx
, new_state
);
2217 _swsetup_InvalidateState( ctx
, new_state
);
2218 _ac_InvalidateState( ctx
, new_state
);
2219 _tnl_InvalidateState( ctx
, new_state
);
2220 _ae_invalidate_state( ctx
, new_state
);
2221 RADEON_CONTEXT(ctx
)->NewGLState
|= new_state
;
2222 radeonVtxfmtInvalidate( ctx
);
2226 /* A hack. Need a faster way to find this out.
2228 static GLboolean
check_material( GLcontext
*ctx
)
2230 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2233 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2234 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2236 if (tnl
->vb
.AttribPtr
[i
] &&
2237 tnl
->vb
.AttribPtr
[i
]->stride
)
2244 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2246 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2247 GLboolean has_material
;
2250 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->NewGLState
);
2254 if (rmesa
->NewGLState
)
2255 radeonValidateState( ctx
);
2257 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2260 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2263 /* Run the pipeline.
2265 _tnl_run_pipeline( ctx
);
2268 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2273 /* Initialize the driver's state functions.
2274 * Many of the ctx->Driver functions might have been initialized to
2275 * software defaults in the earlier _mesa_init_driver_functions() call.
2277 void radeonInitStateFuncs( GLcontext
*ctx
)
2279 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2280 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2282 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2283 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2285 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2286 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2287 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2288 ctx
->Driver
.ClearColor
= radeonClearColor
;
2289 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2290 ctx
->Driver
.ClearIndex
= NULL
;
2291 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2292 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2293 ctx
->Driver
.ColorMask
= radeonColorMask
;
2294 ctx
->Driver
.CullFace
= radeonCullFace
;
2295 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2296 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2297 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2298 ctx
->Driver
.Enable
= radeonEnable
;
2299 ctx
->Driver
.Fogfv
= radeonFogfv
;
2300 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2301 ctx
->Driver
.Hint
= NULL
;
2302 ctx
->Driver
.IndexMask
= NULL
;
2303 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2304 ctx
->Driver
.Lightfv
= radeonLightfv
;
2305 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2306 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2307 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2308 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2310 if (RADEON_CONTEXT(ctx
)->dri
.drmMinor
> 1)
2311 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2313 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2314 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2315 ctx
->Driver
.Scissor
= radeonScissor
;
2316 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2317 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2318 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2319 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2320 ctx
->Driver
.Viewport
= radeonViewport
;
2322 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2323 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;