1 /**************************************************************************
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/state.h"
41 #include "main/context.h"
42 #include "main/framebuffer.h"
43 #include "main/simple_list.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
50 #include "radeon_context.h"
51 #include "radeon_mipmap_tree.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 "drirenderbuffer.h"
59 static void radeonUpdateSpecular( GLcontext
*ctx
);
61 /* =============================================================
65 static void radeonAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
67 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
68 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
71 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
73 RADEON_STATECHANGE( rmesa
, ctx
);
75 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
76 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
80 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
83 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
86 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
89 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
92 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
95 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
98 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
101 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
105 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
108 static void radeonBlendEquationSeparate( GLcontext
*ctx
,
109 GLenum modeRGB
, GLenum modeA
)
111 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
112 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
113 GLboolean fallback
= GL_FALSE
;
115 assert( modeRGB
== modeA
);
120 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
123 case GL_FUNC_SUBTRACT
:
124 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
128 if (ctx
->Color
.BlendEnabled
)
131 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
135 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
137 RADEON_STATECHANGE( rmesa
, ctx
);
138 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
139 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
140 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
141 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
143 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
148 static void radeonBlendFuncSeparate( GLcontext
*ctx
,
149 GLenum sfactorRGB
, GLenum dfactorRGB
,
150 GLenum sfactorA
, GLenum dfactorA
)
152 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
153 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
154 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
155 GLboolean fallback
= GL_FALSE
;
157 switch ( ctx
->Color
.BlendSrcRGB
) {
159 b
|= RADEON_SRC_BLEND_GL_ZERO
;
162 b
|= RADEON_SRC_BLEND_GL_ONE
;
165 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
167 case GL_ONE_MINUS_DST_COLOR
:
168 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
171 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
173 case GL_ONE_MINUS_SRC_COLOR
:
174 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
177 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
179 case GL_ONE_MINUS_SRC_ALPHA
:
180 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
183 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
185 case GL_ONE_MINUS_DST_ALPHA
:
186 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
188 case GL_SRC_ALPHA_SATURATE
:
189 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
191 case GL_CONSTANT_COLOR
:
192 case GL_ONE_MINUS_CONSTANT_COLOR
:
193 case GL_CONSTANT_ALPHA
:
194 case GL_ONE_MINUS_CONSTANT_ALPHA
:
195 if (ctx
->Color
.BlendEnabled
)
198 b
|= RADEON_SRC_BLEND_GL_ONE
;
204 switch ( ctx
->Color
.BlendDstRGB
) {
206 b
|= RADEON_DST_BLEND_GL_ZERO
;
209 b
|= RADEON_DST_BLEND_GL_ONE
;
212 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
214 case GL_ONE_MINUS_SRC_COLOR
:
215 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
218 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
220 case GL_ONE_MINUS_SRC_ALPHA
:
221 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
224 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
226 case GL_ONE_MINUS_DST_COLOR
:
227 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
230 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
232 case GL_ONE_MINUS_DST_ALPHA
:
233 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
235 case GL_CONSTANT_COLOR
:
236 case GL_ONE_MINUS_CONSTANT_COLOR
:
237 case GL_CONSTANT_ALPHA
:
238 case GL_ONE_MINUS_CONSTANT_ALPHA
:
239 if (ctx
->Color
.BlendEnabled
)
242 b
|= RADEON_DST_BLEND_GL_ZERO
;
248 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
250 RADEON_STATECHANGE( rmesa
, ctx
);
251 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
256 /* =============================================================
260 static void radeonDepthFunc( GLcontext
*ctx
, GLenum func
)
262 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
264 RADEON_STATECHANGE( rmesa
, ctx
);
265 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
267 switch ( ctx
->Depth
.Func
) {
269 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
272 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
275 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
278 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
281 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
284 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
287 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
290 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
296 static void radeonDepthMask( GLcontext
*ctx
, GLboolean flag
)
298 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
299 RADEON_STATECHANGE( rmesa
, ctx
);
301 if ( ctx
->Depth
.Mask
) {
302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
304 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
308 static void radeonClearDepth( GLcontext
*ctx
, GLclampd d
)
310 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
311 GLuint format
= (rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &
312 RADEON_DEPTH_FORMAT_MASK
);
315 case RADEON_DEPTH_FORMAT_16BIT_INT_Z
:
316 rmesa
->radeon
.state
.depth
.clear
= d
* 0x0000ffff;
318 case RADEON_DEPTH_FORMAT_24BIT_INT_Z
:
319 rmesa
->radeon
.state
.depth
.clear
= d
* 0x00ffffff;
325 /* =============================================================
330 static void radeonFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
332 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
333 union { int i
; float f
; } c
, d
;
338 if (!ctx
->Fog
.Enabled
)
340 RADEON_STATECHANGE(rmesa
, tcl
);
341 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
342 switch (ctx
->Fog
.Mode
) {
344 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
347 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
350 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
359 if (!ctx
->Fog
.Enabled
)
361 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
362 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
363 switch (ctx
->Fog
.Mode
) {
366 /* While this is the opposite sign from the DDK, it makes the fog test
367 * pass, and matches r200.
369 d
.f
= -ctx
->Fog
.Density
;
373 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
376 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
380 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
381 /* While this is the opposite sign from the DDK, it makes the fog
382 * test pass, and matches r200.
384 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
390 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
391 RADEON_STATECHANGE( rmesa
, fog
);
392 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
393 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
397 RADEON_STATECHANGE( rmesa
, ctx
);
398 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
399 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
400 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
401 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
403 case GL_FOG_COORD_SRC
:
404 radeonUpdateSpecular( ctx
);
411 /* =============================================================
415 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
417 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
418 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
419 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
421 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
422 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
424 if ( ctx
->Polygon
.CullFlag
) {
425 switch ( ctx
->Polygon
.CullFaceMode
) {
427 s
&= ~RADEON_FFACE_SOLID
;
428 t
|= RADEON_CULL_FRONT
;
431 s
&= ~RADEON_BFACE_SOLID
;
432 t
|= RADEON_CULL_BACK
;
434 case GL_FRONT_AND_BACK
:
435 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
436 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
441 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
442 RADEON_STATECHANGE(rmesa
, set
);
443 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
446 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
447 RADEON_STATECHANGE(rmesa
, tcl
);
448 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
452 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
454 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
456 RADEON_STATECHANGE( rmesa
, set
);
457 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
459 RADEON_STATECHANGE( rmesa
, tcl
);
460 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
462 /* Winding is inverted when rendering to FBO */
463 if (ctx
->DrawBuffer
&& ctx
->DrawBuffer
->Name
)
464 mode
= (mode
== GL_CW
) ? GL_CCW
: GL_CW
;
468 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
471 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
472 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
478 /* =============================================================
481 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
483 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
485 RADEON_STATECHANGE( rmesa
, lin
);
486 RADEON_STATECHANGE( rmesa
, set
);
488 /* Line width is stored in U6.4 format.
490 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
491 if ( widthf
> 1.0 ) {
492 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
494 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
498 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
500 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
502 RADEON_STATECHANGE( rmesa
, lin
);
503 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
504 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
508 /* =============================================================
511 static void radeonColorMask( GLcontext
*ctx
,
512 GLboolean r
, GLboolean g
,
513 GLboolean b
, GLboolean a
)
515 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
516 struct radeon_renderbuffer
*rrb
;
519 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
523 mask
= radeonPackColor( rrb
->cpp
,
524 ctx
->Color
.ColorMask
[RCOMP
],
525 ctx
->Color
.ColorMask
[GCOMP
],
526 ctx
->Color
.ColorMask
[BCOMP
],
527 ctx
->Color
.ColorMask
[ACOMP
] );
529 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
530 RADEON_STATECHANGE( rmesa
, msk
);
531 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
536 /* =============================================================
540 static void radeonPolygonOffset( GLcontext
*ctx
,
541 GLfloat factor
, GLfloat units
)
543 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
544 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
545 float_ui32_type constant
= { units
* depthScale
};
546 float_ui32_type factoru
= { factor
};
548 RADEON_STATECHANGE( rmesa
, zbs
);
549 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
550 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
553 static void radeonPolygonStipplePreKMS( GLcontext
*ctx
, const GLubyte
*mask
)
555 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
557 drm_radeon_stipple_t stipple
;
559 /* Must flip pattern upside down.
561 for ( i
= 0 ; i
< 32 ; i
++ ) {
562 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
565 /* TODO: push this into cmd mechanism
567 radeon_firevertices(&rmesa
->radeon
);
568 LOCK_HARDWARE( &rmesa
->radeon
);
570 /* FIXME: Use window x,y offsets into stipple RAM.
572 stipple
.mask
= rmesa
->state
.stipple
.mask
;
573 drmCommandWrite( rmesa
->radeon
.dri
.fd
, DRM_RADEON_STIPPLE
,
574 &stipple
, sizeof(drm_radeon_stipple_t
) );
575 UNLOCK_HARDWARE( &rmesa
->radeon
);
578 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
580 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
581 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
583 /* Can't generally do unfilled via tcl, but some good special
586 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
587 if (rmesa
->radeon
.TclFallback
) {
588 radeonChooseRenderState( ctx
);
589 radeonChooseVertexState( ctx
);
594 /* =============================================================
595 * Rendering attributes
597 * We really don't want to recalculate all this every time we bind a
598 * texture. These things shouldn't change all that often, so it makes
599 * sense to break them out of the core texture state update routines.
602 /* Examine lighting and texture state to determine if separate specular
605 static void radeonUpdateSpecular( GLcontext
*ctx
)
607 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
608 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
611 RADEON_STATECHANGE( rmesa
, tcl
);
613 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
614 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
615 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
616 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
617 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
619 p
&= ~RADEON_SPECULAR_ENABLE
;
621 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
624 if (ctx
->Light
.Enabled
&&
625 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
626 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
627 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
628 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
629 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
630 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
631 p
|= RADEON_SPECULAR_ENABLE
;
632 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
633 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
635 else if (ctx
->Light
.Enabled
) {
636 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
637 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
638 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
639 } else if (ctx
->Fog
.ColorSumEnabled
) {
640 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
641 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
642 p
|= RADEON_SPECULAR_ENABLE
;
644 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
647 if (ctx
->Fog
.Enabled
) {
648 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
649 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
650 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
651 /* Bizzare: have to leave lighting enabled to get fog. */
652 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
655 /* cannot do tcl fog factor calculation with fog coord source
656 * (send precomputed factors). Cannot use precomputed fog
657 * factors together with tcl spec light (need tcl fallback) */
658 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
659 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
663 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
665 if (NEED_SECONDARY_COLOR(ctx
)) {
666 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
668 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
671 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
672 RADEON_STATECHANGE( rmesa
, ctx
);
673 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
676 /* Update vertex/render formats
678 if (rmesa
->radeon
.TclFallback
) {
679 radeonChooseRenderState( ctx
);
680 radeonChooseVertexState( ctx
);
685 /* =============================================================
690 /* Update on colormaterial, material emmissive/ambient,
691 * lightmodel.globalambient
693 static void update_global_ambient( GLcontext
*ctx
)
695 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
696 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
698 /* Need to do more if both emmissive & ambient are PREMULT:
699 * Hope this is not needed for MULT
701 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
702 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
703 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
705 COPY_3V( &fcmd
[GLT_RED
],
706 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
707 ACC_SCALE_3V( &fcmd
[GLT_RED
],
708 ctx
->Light
.Model
.Ambient
,
709 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
713 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
716 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
719 /* Update on change to
723 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
725 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
727 /* fprintf(stderr, "%s\n", __FUNCTION__); */
730 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
731 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
733 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
734 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
735 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
737 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
741 /* Also fallback for asym colormaterial mode in twoside lighting...
743 static void check_twoside_fallback( GLcontext
*ctx
)
745 GLboolean fallback
= GL_FALSE
;
748 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
749 if (ctx
->Light
.ColorMaterialEnabled
&&
750 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
751 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
754 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
755 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
756 ctx
->Light
.Material
.Attrib
[i
+1],
757 sizeof(GLfloat
)*4) != 0) {
764 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
768 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
770 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
771 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
773 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
774 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
775 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
776 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
778 if (ctx
->Light
.ColorMaterialEnabled
) {
779 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
781 if (mask
& MAT_BIT_FRONT_EMISSION
) {
782 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
783 RADEON_EMISSIVE_SOURCE_SHIFT
);
786 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
787 RADEON_EMISSIVE_SOURCE_SHIFT
);
790 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
791 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
792 RADEON_AMBIENT_SOURCE_SHIFT
);
795 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
796 RADEON_AMBIENT_SOURCE_SHIFT
);
799 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
800 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
801 RADEON_DIFFUSE_SOURCE_SHIFT
);
804 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
805 RADEON_DIFFUSE_SOURCE_SHIFT
);
808 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
809 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
810 RADEON_SPECULAR_SOURCE_SHIFT
);
813 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
814 RADEON_SPECULAR_SOURCE_SHIFT
);
820 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
821 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
822 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
823 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
826 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
827 RADEON_STATECHANGE( rmesa
, tcl
);
828 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
832 void radeonUpdateMaterial( GLcontext
*ctx
)
834 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
835 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
836 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
839 if (ctx
->Light
.ColorMaterialEnabled
)
840 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
842 if (RADEON_DEBUG
& RADEON_STATE
)
843 fprintf(stderr
, "%s\n", __FUNCTION__
);
846 if (mask
& MAT_BIT_FRONT_EMISSION
) {
847 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
848 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
849 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
850 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
852 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
853 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
854 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
855 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
856 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
858 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
859 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
860 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
861 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
862 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
864 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
865 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
866 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
867 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
868 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
870 if (mask
& MAT_BIT_FRONT_SHININESS
) {
871 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
874 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
876 check_twoside_fallback( ctx
);
877 /* update_global_ambient( ctx );*/
882 * _MESA_NEW_NEED_EYE_COORDS
884 * Uses derived state from mesa:
893 * which are calculated in light.c and are correct for the current
894 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
895 * and _MESA_NEW_NEED_EYE_COORDS.
897 static void update_light( GLcontext
*ctx
)
899 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
901 /* Have to check these, or have an automatic shortcircuit mechanism
902 * to remove noop statechanges. (Or just do a better job on the
906 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
908 if (ctx
->_NeedEyeCoords
)
909 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
911 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
914 /* Leave this test disabled: (unexplained q3 lockup) (even with
917 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
919 RADEON_STATECHANGE( rmesa
, tcl
);
920 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
925 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
926 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
927 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
928 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
929 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
930 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
935 if (ctx
->Light
.Enabled
) {
937 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
938 if (ctx
->Light
.Light
[p
].Enabled
) {
939 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
940 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
942 if (l
->EyePosition
[3] == 0.0) {
943 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
944 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
945 fcmd
[LIT_POSITION_W
] = 0;
946 fcmd
[LIT_DIRECTION_W
] = 0;
948 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
949 fcmd
[LIT_DIRECTION_X
] = -l
->_NormSpotDirection
[0];
950 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormSpotDirection
[1];
951 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormSpotDirection
[2];
952 fcmd
[LIT_DIRECTION_W
] = 0;
955 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
961 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
962 GLenum pname
, const GLfloat
*params
)
964 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
965 GLint p
= light
- GL_LIGHT0
;
966 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
967 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
974 update_light_colors( ctx
, p
);
977 case GL_SPOT_DIRECTION
:
978 /* picked up in update_light */
982 /* positions picked up in update_light, but can do flag here */
984 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
986 /* FIXME: Set RANGE_ATTEN only when needed */
988 flag
= RADEON_LIGHT_1_IS_LOCAL
;
990 flag
= RADEON_LIGHT_0_IS_LOCAL
;
992 RADEON_STATECHANGE(rmesa
, tcl
);
993 if (l
->EyePosition
[3] != 0.0F
)
994 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
996 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1000 case GL_SPOT_EXPONENT
:
1001 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1002 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
1005 case GL_SPOT_CUTOFF
: {
1006 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
1007 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1009 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1010 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
1012 RADEON_STATECHANGE(rmesa
, tcl
);
1013 if (l
->SpotCutoff
!= 180.0F
)
1014 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1016 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1021 case GL_CONSTANT_ATTENUATION
:
1022 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1023 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1024 if ( params
[0] == 0.0 )
1025 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1027 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1029 case GL_LINEAR_ATTENUATION
:
1030 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1031 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1033 case GL_QUADRATIC_ATTENUATION
:
1034 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1035 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1041 /* Set RANGE_ATTEN only when needed */
1044 case GL_CONSTANT_ATTENUATION
:
1045 case GL_LINEAR_ATTENUATION
:
1046 case GL_QUADRATIC_ATTENUATION
:
1048 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1049 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1050 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1051 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1052 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1053 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1055 if ( l
->EyePosition
[3] == 0.0F
||
1056 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1057 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1058 /* Disable attenuation */
1059 icmd
[idx
] &= ~atten_flag
;
1061 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1062 /* Enable only constant portion of attenuation calculation */
1063 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1065 /* Enable full attenuation calculation */
1066 icmd
[idx
] &= ~atten_const_flag
;
1067 icmd
[idx
] |= atten_flag
;
1071 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1082 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1083 const GLfloat
*param
)
1085 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1088 case GL_LIGHT_MODEL_AMBIENT
:
1089 update_global_ambient( ctx
);
1092 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1093 RADEON_STATECHANGE( rmesa
, tcl
);
1094 if (ctx
->Light
.Model
.LocalViewer
)
1095 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1097 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1100 case GL_LIGHT_MODEL_TWO_SIDE
:
1101 RADEON_STATECHANGE( rmesa
, tcl
);
1102 if (ctx
->Light
.Model
.TwoSide
)
1103 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1105 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1107 check_twoside_fallback( ctx
);
1109 if (rmesa
->radeon
.TclFallback
) {
1110 radeonChooseRenderState( ctx
);
1111 radeonChooseVertexState( ctx
);
1115 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1116 radeonUpdateSpecular(ctx
);
1124 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1126 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1127 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1129 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1130 RADEON_ALPHA_SHADE_MASK
|
1131 RADEON_SPECULAR_SHADE_MASK
|
1132 RADEON_FOG_SHADE_MASK
);
1136 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1137 RADEON_ALPHA_SHADE_FLAT
|
1138 RADEON_SPECULAR_SHADE_FLAT
|
1139 RADEON_FOG_SHADE_FLAT
);
1142 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1143 RADEON_ALPHA_SHADE_GOURAUD
|
1144 RADEON_SPECULAR_SHADE_GOURAUD
|
1145 RADEON_FOG_SHADE_GOURAUD
);
1151 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1152 RADEON_STATECHANGE( rmesa
, set
);
1153 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1158 /* =============================================================
1162 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1164 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1165 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1166 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1168 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1169 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1170 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1171 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1172 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1175 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1177 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1180 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1181 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1182 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1184 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1185 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1186 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1187 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1188 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1194 /* =============================================================
1199 radeonStencilFuncSeparate( GLcontext
*ctx
, GLenum face
, GLenum func
,
1200 GLint ref
, GLuint mask
)
1202 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1203 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << RADEON_STENCIL_REF_SHIFT
) |
1204 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1206 RADEON_STATECHANGE( rmesa
, ctx
);
1207 RADEON_STATECHANGE( rmesa
, msk
);
1209 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1210 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1211 RADEON_STENCIL_VALUE_MASK
);
1213 switch ( ctx
->Stencil
.Function
[0] ) {
1215 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1218 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1221 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1224 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1227 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1230 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1233 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1236 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1240 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1244 radeonStencilMaskSeparate( GLcontext
*ctx
, GLenum face
, GLuint mask
)
1246 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1248 RADEON_STATECHANGE( rmesa
, msk
);
1249 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1250 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1251 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1254 static void radeonStencilOpSeparate( GLcontext
*ctx
, GLenum face
, GLenum fail
,
1255 GLenum zfail
, GLenum zpass
)
1257 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1259 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1260 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1261 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1263 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1264 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1265 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1266 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1267 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1268 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1270 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1271 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1272 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1273 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1274 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1275 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1276 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1279 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1280 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1281 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1282 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1283 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1284 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1287 RADEON_STATECHANGE( rmesa
, ctx
);
1288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1289 RADEON_STENCIL_ZFAIL_MASK
|
1290 RADEON_STENCIL_ZPASS_MASK
);
1292 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1294 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1297 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1303 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1306 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1309 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1312 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1315 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1319 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1321 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1324 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1327 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1330 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1333 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1336 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1339 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1342 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1346 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1348 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1351 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1354 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1357 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1360 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1363 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1366 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1369 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1374 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1376 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1378 rmesa
->radeon
.state
.stencil
.clear
=
1379 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
1380 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1381 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
));
1385 /* =============================================================
1386 * Window position and viewport transformation
1390 * To correctly position primitives:
1392 #define SUBPIXEL_X 0.125
1393 #define SUBPIXEL_Y 0.125
1397 * Called when window size or position changes or viewport or depth range
1398 * state is changed. We update the hardware viewport state here.
1400 void radeonUpdateWindow( GLcontext
*ctx
)
1402 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1403 __DRIdrawablePrivate
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1404 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
1405 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
1406 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1407 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
? (ctx
->DrawBuffer
->Name
!= 0) : 0);
1408 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1409 GLfloat y_scale
, y_bias
;
1411 if (render_to_fbo
) {
1419 float_ui32_type sx
= { v
[MAT_SX
] };
1420 float_ui32_type tx
= { v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
};
1421 float_ui32_type sy
= { v
[MAT_SY
] * y_scale
};
1422 float_ui32_type ty
= { (v
[MAT_TY
] * y_scale
) + y_bias
+ SUBPIXEL_Y
};
1423 float_ui32_type sz
= { v
[MAT_SZ
] * depthScale
};
1424 float_ui32_type tz
= { v
[MAT_TZ
] * depthScale
};
1426 RADEON_STATECHANGE( rmesa
, vpt
);
1428 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1429 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1430 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1431 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1432 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1433 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1437 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1438 GLsizei width
, GLsizei height
)
1440 /* Don't pipeline viewport changes, conflict with window offset
1441 * setting below. Could apply deltas to rescue pipelined viewport
1442 * values, or keep the originals hanging around.
1444 radeonUpdateWindow( ctx
);
1446 radeon_viewport(ctx
, x
, y
, width
, height
);
1449 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1452 radeonUpdateWindow( ctx
);
1455 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1457 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1458 __DRIdrawablePrivate
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1459 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1460 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1461 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1466 tx
.f
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1467 ty
.f
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1469 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != tx
.ui32
||
1470 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != ty
.ui32
)
1472 /* Note: this should also modify whatever data the context reset
1475 RADEON_STATECHANGE( rmesa
, vpt
);
1476 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1477 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1479 /* update polygon stipple x/y screen offset */
1482 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1484 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1485 RADEON_STIPPLE_Y_OFFSET_MASK
);
1487 /* add magic offsets, then invert */
1488 stx
= 31 - ((dPriv
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1489 sty
= 31 - ((dPriv
->y
+ dPriv
->h
- 1)
1490 & RADEON_STIPPLE_COORD_MASK
);
1492 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1493 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1495 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1496 RADEON_STATECHANGE( rmesa
, msc
);
1497 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1502 radeonUpdateScissor( ctx
);
1507 /* =============================================================
1511 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1513 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1515 struct radeon_renderbuffer
*rrb
;
1517 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
1521 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1522 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1523 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1524 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1525 rmesa
->radeon
.state
.color
.clear
= radeonPackColor( rrb
->cpp
,
1526 c
[0], c
[1], c
[2], c
[3] );
1530 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1532 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1533 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1537 static GLuint radeon_rop_tab
[] = {
1540 RADEON_ROP_AND_REVERSE
,
1542 RADEON_ROP_AND_INVERTED
,
1549 RADEON_ROP_OR_REVERSE
,
1550 RADEON_ROP_COPY_INVERTED
,
1551 RADEON_ROP_OR_INVERTED
,
1556 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1558 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1559 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1563 RADEON_STATECHANGE( rmesa
, msk
);
1564 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1567 /* =============================================================
1568 * State enable/disable
1571 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1573 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1576 if ( RADEON_DEBUG
& RADEON_STATE
)
1577 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1578 _mesa_lookup_enum_by_nr( cap
),
1579 state
? "GL_TRUE" : "GL_FALSE" );
1582 /* Fast track this one...
1590 RADEON_STATECHANGE( rmesa
, ctx
);
1592 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1594 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1599 RADEON_STATECHANGE( rmesa
, ctx
);
1601 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1603 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1605 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1606 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1607 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1609 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1612 /* Catch a possible fallback:
1615 ctx
->Driver
.BlendEquationSeparate( ctx
,
1616 ctx
->Color
.BlendEquationRGB
,
1617 ctx
->Color
.BlendEquationA
);
1618 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1619 ctx
->Color
.BlendDstRGB
,
1620 ctx
->Color
.BlendSrcA
,
1621 ctx
->Color
.BlendDstA
);
1624 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1625 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1629 case GL_CLIP_PLANE0
:
1630 case GL_CLIP_PLANE1
:
1631 case GL_CLIP_PLANE2
:
1632 case GL_CLIP_PLANE3
:
1633 case GL_CLIP_PLANE4
:
1634 case GL_CLIP_PLANE5
:
1635 p
= cap
-GL_CLIP_PLANE0
;
1636 RADEON_STATECHANGE( rmesa
, tcl
);
1638 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1639 radeonClipPlane( ctx
, cap
, NULL
);
1642 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1646 case GL_COLOR_MATERIAL
:
1647 radeonColorMaterial( ctx
, 0, 0 );
1648 radeonUpdateMaterial( ctx
);
1652 radeonCullFace( ctx
, 0 );
1656 RADEON_STATECHANGE(rmesa
, ctx
);
1658 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1660 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1665 RADEON_STATECHANGE(rmesa
, ctx
);
1667 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1668 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->radeon
.state
.color
.roundEnable
;
1670 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1671 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->radeon
.state
.color
.roundEnable
;
1676 RADEON_STATECHANGE(rmesa
, ctx
);
1678 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1679 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1681 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1682 RADEON_STATECHANGE(rmesa
, tcl
);
1683 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1685 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1686 _mesa_allow_light_in_model( ctx
, !state
);
1697 RADEON_STATECHANGE(rmesa
, tcl
);
1698 p
= cap
- GL_LIGHT0
;
1700 flag
= (RADEON_LIGHT_1_ENABLE
|
1701 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1702 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1704 flag
= (RADEON_LIGHT_0_ENABLE
|
1705 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1706 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1709 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1711 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1715 update_light_colors( ctx
, p
);
1719 RADEON_STATECHANGE(rmesa
, tcl
);
1720 radeonUpdateSpecular(ctx
);
1721 check_twoside_fallback( ctx
);
1724 case GL_LINE_SMOOTH
:
1725 RADEON_STATECHANGE( rmesa
, ctx
);
1727 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1729 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1733 case GL_LINE_STIPPLE
:
1734 RADEON_STATECHANGE( rmesa
, ctx
);
1736 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1738 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1742 case GL_COLOR_LOGIC_OP
:
1743 RADEON_STATECHANGE( rmesa
, ctx
);
1744 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1745 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1746 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1748 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1753 RADEON_STATECHANGE( rmesa
, tcl
);
1755 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1757 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1761 case GL_POLYGON_OFFSET_POINT
:
1762 RADEON_STATECHANGE( rmesa
, set
);
1764 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1766 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1770 case GL_POLYGON_OFFSET_LINE
:
1771 RADEON_STATECHANGE( rmesa
, set
);
1773 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1775 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1779 case GL_POLYGON_OFFSET_FILL
:
1780 RADEON_STATECHANGE( rmesa
, set
);
1782 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1784 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1788 case GL_POLYGON_SMOOTH
:
1789 RADEON_STATECHANGE( rmesa
, ctx
);
1791 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1793 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1797 case GL_POLYGON_STIPPLE
:
1798 RADEON_STATECHANGE(rmesa
, ctx
);
1800 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1802 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1806 case GL_RESCALE_NORMAL_EXT
: {
1807 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1808 RADEON_STATECHANGE( rmesa
, tcl
);
1810 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1812 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1817 case GL_SCISSOR_TEST
:
1818 radeon_firevertices(&rmesa
->radeon
);
1819 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1820 radeonUpdateScissor( ctx
);
1823 case GL_STENCIL_TEST
:
1825 GLboolean hw_stencil
= GL_FALSE
;
1826 if (ctx
->DrawBuffer
) {
1827 struct radeon_renderbuffer
*rrbStencil
1828 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
1829 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
1833 RADEON_STATECHANGE( rmesa
, ctx
);
1835 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1837 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1840 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1845 case GL_TEXTURE_GEN_Q
:
1846 case GL_TEXTURE_GEN_R
:
1847 case GL_TEXTURE_GEN_S
:
1848 case GL_TEXTURE_GEN_T
:
1849 /* Picked up in radeonUpdateTextureState.
1851 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1854 case GL_COLOR_SUM_EXT
:
1855 radeonUpdateSpecular ( ctx
);
1864 static void radeonLightingSpaceChange( GLcontext
*ctx
)
1866 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1868 RADEON_STATECHANGE( rmesa
, tcl
);
1870 if (RADEON_DEBUG
& RADEON_STATE
)
1871 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1872 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1874 if (ctx
->_NeedEyeCoords
)
1875 tmp
= ctx
->Transform
.RescaleNormals
;
1877 tmp
= !ctx
->Transform
.RescaleNormals
;
1880 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1882 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1885 if (RADEON_DEBUG
& RADEON_STATE
)
1886 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1887 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1890 /* =============================================================
1891 * Deferred state management - matrices, textures, other?
1895 void radeonUploadTexMatrix( r100ContextPtr rmesa
,
1896 int unit
, GLboolean swapcols
)
1898 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1899 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1900 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1901 texgen generates all 4 coords, at least tests with projtex indicated that.
1902 So: if we need the q coord in the end (solely determined by the texture
1903 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1904 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1905 column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
1906 will get submitted in the "wrong", i.e. 3rd, slot.
1907 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1908 size and using the texture matrix to swap the r and q coords around (ut2k3
1909 does exactly that), so we don't need the 3rd / 4th column swap - still need
1910 the 3rd / 4th row swap of course. This will potentially break for apps which
1911 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1912 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1913 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1914 incredibly hard to detect so we can't just fallback in such a case. Assume
1915 it never happens... - rs
1918 int idx
= TEXMAT_0
+ unit
;
1919 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
1921 struct gl_texture_unit tUnit
= rmesa
->radeon
.glCtx
->Texture
.Unit
[unit
];
1922 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
1924 rmesa
->TexMatColSwap
&= ~(1 << unit
);
1925 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
1927 rmesa
->TexMatColSwap
|= 1 << unit
;
1928 /* attention some elems are swapped 2 times! */
1941 /* those last 4 are probably never used */
1948 for (i
= 0; i
< 2; i
++) {
1952 *dest
++ = src
[i
+12];
1954 for (i
= 3; i
>= 2; i
--) {
1958 *dest
++ = src
[i
+12];
1963 for (i
= 0 ; i
< 4 ; i
++) {
1967 *dest
++ = src
[i
+12];
1971 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1975 static void upload_matrix( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1977 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1981 for (i
= 0 ; i
< 4 ; i
++) {
1985 *dest
++ = src
[i
+12];
1988 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1991 static void upload_matrix_t( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1993 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1994 memcpy(dest
, src
, 16*sizeof(float));
1995 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1999 static void update_texturematrix( GLcontext
*ctx
)
2001 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
2002 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
2003 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2005 GLuint texMatEnabled
= 0;
2006 rmesa
->NeedTexMatrix
= 0;
2007 rmesa
->TexMatColSwap
= 0;
2009 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
2010 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2011 GLboolean needMatrix
= GL_FALSE
;
2012 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2013 needMatrix
= GL_TRUE
;
2014 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2015 RADEON_TEXMAT_0_ENABLE
) << unit
;
2017 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2018 /* Need to preconcatenate any active texgen
2019 * obj/eyeplane matrices:
2021 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
2022 ctx
->TextureMatrixStack
[unit
].Top
,
2023 &rmesa
->TexGenMatrix
[unit
] );
2026 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
2027 ctx
->TextureMatrixStack
[unit
].Top
);
2030 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2031 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
2032 needMatrix
= GL_TRUE
;
2035 rmesa
->NeedTexMatrix
|= 1 << unit
;
2036 radeonUploadTexMatrix( rmesa
, unit
,
2037 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
2042 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
2044 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2045 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2046 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
2047 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
2049 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
2050 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
2051 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
2052 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
2053 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
2054 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
2056 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2057 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2059 RADEON_STATECHANGE(rmesa
, tcl
);
2060 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2061 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2065 static GLboolean
r100ValidateBuffers(GLcontext
*ctx
)
2067 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2068 struct radeon_renderbuffer
*rrb
;
2071 radeon_cs_space_reset_bos(rmesa
->radeon
.cmdbuf
.cs
);
2073 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
2075 if (rrb
&& rrb
->bo
) {
2076 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
2077 0, RADEON_GEM_DOMAIN_VRAM
);
2081 rrb
= radeon_get_depthbuffer(&rmesa
->radeon
);
2083 if (rrb
&& rrb
->bo
) {
2084 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
2085 0, RADEON_GEM_DOMAIN_VRAM
);
2088 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; ++i
) {
2091 if (!ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2094 t
= rmesa
->state
.texture
.unit
[i
].texobj
;
2095 if (t
->image_override
&& t
->bo
)
2096 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->bo
,
2097 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
2099 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->mt
->bo
,
2100 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
2103 ret
= radeon_cs_space_check_with_bo(rmesa
->radeon
.cmdbuf
.cs
, first_elem(&rmesa
->radeon
.dma
.reserved
)->bo
, RADEON_GEM_DOMAIN_GTT
, 0);
2109 GLboolean
radeonValidateState( GLcontext
*ctx
)
2111 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2112 GLuint new_state
= rmesa
->radeon
.NewGLState
;
2114 if (new_state
& _NEW_BUFFERS
) {
2115 _mesa_update_framebuffer(ctx
);
2116 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2117 _mesa_update_draw_buffer_bounds(ctx
);
2118 RADEON_STATECHANGE(rmesa
, ctx
);
2121 if (new_state
& _NEW_TEXTURE
) {
2122 radeonUpdateTextureState( ctx
);
2123 new_state
|= rmesa
->radeon
.NewGLState
; /* may add TEXTURE_MATRIX */
2126 /* we need to do a space check here */
2127 if (!r100ValidateBuffers(ctx
))
2130 /* Need an event driven matrix update?
2132 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2133 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2135 /* Need these for lighting (shouldn't upload otherwise)
2137 if (new_state
& (_NEW_MODELVIEW
)) {
2138 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2139 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2142 /* Does this need to be triggered on eg. modelview for
2143 * texgen-derived objplane/eyeplane matrices?
2145 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2146 update_texturematrix( ctx
);
2149 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2150 update_light( ctx
);
2153 /* emit all active clip planes if projection matrix changes.
2155 if (new_state
& (_NEW_PROJECTION
)) {
2156 if (ctx
->Transform
.ClipPlanesEnabled
)
2157 radeonUpdateClipPlanes( ctx
);
2161 rmesa
->radeon
.NewGLState
= 0;
2167 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2169 _swrast_InvalidateState( ctx
, new_state
);
2170 _swsetup_InvalidateState( ctx
, new_state
);
2171 _vbo_InvalidateState( ctx
, new_state
);
2172 _tnl_InvalidateState( ctx
, new_state
);
2173 _ae_invalidate_state( ctx
, new_state
);
2174 R100_CONTEXT(ctx
)->radeon
.NewGLState
|= new_state
;
2178 /* A hack. Need a faster way to find this out.
2180 static GLboolean
check_material( GLcontext
*ctx
)
2182 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2185 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2186 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2188 if (tnl
->vb
.AttribPtr
[i
] &&
2189 tnl
->vb
.AttribPtr
[i
]->stride
)
2196 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2198 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2199 GLboolean has_material
;
2202 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->radeon
.NewGLState
);
2206 if (rmesa
->radeon
.NewGLState
)
2207 if (!radeonValidateState( ctx
))
2208 FALLBACK(rmesa
, RADEON_FALLBACK_TEXTURE
, GL_TRUE
);
2210 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2213 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2216 /* Run the pipeline.
2218 _tnl_run_pipeline( ctx
);
2221 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2225 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
2227 r100ContextPtr r100
= R100_CONTEXT(ctx
);
2230 radeon_firevertices(&r100
->radeon
);
2232 RADEON_STATECHANGE(r100
, stp
);
2234 /* Must flip pattern upside down.
2236 for ( i
= 31 ; i
>= 0; i
--) {
2237 r100
->hw
.stp
.cmd
[3 + i
] = ((GLuint
*) mask
)[i
];
2242 /* Initialize the driver's state functions.
2243 * Many of the ctx->Driver functions might have been initialized to
2244 * software defaults in the earlier _mesa_init_driver_functions() call.
2246 void radeonInitStateFuncs( GLcontext
*ctx
, GLboolean dri2
)
2248 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2249 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2251 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2252 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2254 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2255 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2256 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2257 ctx
->Driver
.ClearColor
= radeonClearColor
;
2258 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2259 ctx
->Driver
.ClearIndex
= NULL
;
2260 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2261 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2262 ctx
->Driver
.ColorMask
= radeonColorMask
;
2263 ctx
->Driver
.CullFace
= radeonCullFace
;
2264 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2265 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2266 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2267 ctx
->Driver
.Enable
= radeonEnable
;
2268 ctx
->Driver
.Fogfv
= radeonFogfv
;
2269 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2270 ctx
->Driver
.Hint
= NULL
;
2271 ctx
->Driver
.IndexMask
= NULL
;
2272 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2273 ctx
->Driver
.Lightfv
= radeonLightfv
;
2274 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2275 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2276 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2277 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2278 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2280 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2282 ctx
->Driver
.PolygonStipple
= radeonPolygonStipplePreKMS
;
2283 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2284 ctx
->Driver
.Scissor
= radeonScissor
;
2285 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2286 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2287 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2288 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2289 ctx
->Driver
.Viewport
= radeonViewport
;
2291 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2292 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;