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/context.h"
41 #include "main/framebuffer.h"
42 #include "main/simple_list.h"
43 #include "main/state.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "drivers/common/meta.h"
51 #include "radeon_context.h"
52 #include "radeon_mipmap_tree.h"
53 #include "radeon_ioctl.h"
54 #include "radeon_state.h"
55 #include "radeon_tcl.h"
56 #include "radeon_tex.h"
57 #include "radeon_swtcl.h"
59 static void radeonUpdateSpecular( struct gl_context
*ctx
);
61 /* =============================================================
65 static void radeonAlphaFunc( struct gl_context
*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( struct gl_context
*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
.Blend
[0].EquationRGB
== 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( struct gl_context
*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
.Blend
[0].SrcRGB
) {
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
.Blend
[0].DstRGB
) {
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( struct gl_context
*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( struct gl_context
*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
;
309 /* =============================================================
314 static void radeonFogfv( struct gl_context
*ctx
, GLenum pname
, const GLfloat
*param
)
316 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
317 union { int i
; float f
; } c
, d
;
322 if (!ctx
->Fog
.Enabled
)
324 RADEON_STATECHANGE(rmesa
, tcl
);
325 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
326 switch (ctx
->Fog
.Mode
) {
328 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
331 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
334 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
343 if (!ctx
->Fog
.Enabled
)
345 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
346 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
347 switch (ctx
->Fog
.Mode
) {
350 /* While this is the opposite sign from the DDK, it makes the fog test
351 * pass, and matches r200.
353 d
.f
= -ctx
->Fog
.Density
;
357 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
360 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
364 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
365 /* While this is the opposite sign from the DDK, it makes the fog
366 * test pass, and matches r200.
368 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
374 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
375 RADEON_STATECHANGE( rmesa
, fog
);
376 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
377 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
381 RADEON_STATECHANGE( rmesa
, ctx
);
382 _mesa_unclamped_float_rgba_to_ubyte(col
, ctx
->Fog
.Color
);
383 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
384 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
385 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
387 case GL_FOG_COORD_SRC
:
388 radeonUpdateSpecular( ctx
);
395 /* =============================================================
399 static void radeonCullFace( struct gl_context
*ctx
, GLenum unused
)
401 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
402 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
403 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
405 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
406 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
408 if ( ctx
->Polygon
.CullFlag
) {
409 switch ( ctx
->Polygon
.CullFaceMode
) {
411 s
&= ~RADEON_FFACE_SOLID
;
412 t
|= RADEON_CULL_FRONT
;
415 s
&= ~RADEON_BFACE_SOLID
;
416 t
|= RADEON_CULL_BACK
;
418 case GL_FRONT_AND_BACK
:
419 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
420 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
425 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
426 RADEON_STATECHANGE(rmesa
, set
);
427 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
430 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
431 RADEON_STATECHANGE(rmesa
, tcl
);
432 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
436 static void radeonFrontFace( struct gl_context
*ctx
, GLenum mode
)
438 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
440 RADEON_STATECHANGE( rmesa
, set
);
441 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
443 RADEON_STATECHANGE( rmesa
, tcl
);
444 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
446 /* Winding is inverted when rendering to FBO */
447 if (ctx
->DrawBuffer
&& ctx
->DrawBuffer
->Name
)
448 mode
= (mode
== GL_CW
) ? GL_CCW
: GL_CW
;
452 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
455 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
456 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
462 /* =============================================================
465 static void radeonLineWidth( struct gl_context
*ctx
, GLfloat widthf
)
467 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
469 RADEON_STATECHANGE( rmesa
, lin
);
470 RADEON_STATECHANGE( rmesa
, set
);
472 /* Line width is stored in U6.4 format.
474 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
475 if ( widthf
> 1.0 ) {
476 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
478 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
482 static void radeonLineStipple( struct gl_context
*ctx
, GLint factor
, GLushort pattern
)
484 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
486 RADEON_STATECHANGE( rmesa
, lin
);
487 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
488 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
492 /* =============================================================
495 static void radeonColorMask( struct gl_context
*ctx
,
496 GLboolean r
, GLboolean g
,
497 GLboolean b
, GLboolean a
)
499 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
500 struct radeon_renderbuffer
*rrb
;
503 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
507 mask
= radeonPackColor( rrb
->cpp
,
508 ctx
->Color
.ColorMask
[0][RCOMP
],
509 ctx
->Color
.ColorMask
[0][GCOMP
],
510 ctx
->Color
.ColorMask
[0][BCOMP
],
511 ctx
->Color
.ColorMask
[0][ACOMP
] );
513 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
514 RADEON_STATECHANGE( rmesa
, msk
);
515 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
520 /* =============================================================
524 static void radeonPolygonOffset( struct gl_context
*ctx
,
525 GLfloat factor
, GLfloat units
)
527 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
528 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
529 float_ui32_type constant
= { units
* depthScale
};
530 float_ui32_type factoru
= { factor
};
532 RADEON_STATECHANGE( rmesa
, zbs
);
533 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
534 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
537 static void radeonPolygonMode( struct gl_context
*ctx
, GLenum face
, GLenum mode
)
539 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
540 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
542 /* Can't generally do unfilled via tcl, but some good special
545 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
546 if (rmesa
->radeon
.TclFallback
) {
547 radeonChooseRenderState( ctx
);
548 radeonChooseVertexState( ctx
);
553 /* =============================================================
554 * Rendering attributes
556 * We really don't want to recalculate all this every time we bind a
557 * texture. These things shouldn't change all that often, so it makes
558 * sense to break them out of the core texture state update routines.
561 /* Examine lighting and texture state to determine if separate specular
564 static void radeonUpdateSpecular( struct gl_context
*ctx
)
566 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
567 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
570 RADEON_STATECHANGE( rmesa
, tcl
);
572 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
573 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
574 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
575 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
576 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
578 p
&= ~RADEON_SPECULAR_ENABLE
;
580 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
583 if (ctx
->Light
.Enabled
&&
584 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
585 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
586 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
587 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
588 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
589 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
590 p
|= RADEON_SPECULAR_ENABLE
;
591 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
592 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
594 else if (ctx
->Light
.Enabled
) {
595 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
596 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
597 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
598 } else if (ctx
->Fog
.ColorSumEnabled
) {
599 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
600 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
601 p
|= RADEON_SPECULAR_ENABLE
;
603 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
606 if (ctx
->Fog
.Enabled
) {
607 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
608 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
609 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
610 /* Bizzare: have to leave lighting enabled to get fog. */
611 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
614 /* cannot do tcl fog factor calculation with fog coord source
615 * (send precomputed factors). Cannot use precomputed fog
616 * factors together with tcl spec light (need tcl fallback) */
617 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
618 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
622 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
624 if (_mesa_need_secondary_color(ctx
)) {
625 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
627 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
630 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
631 RADEON_STATECHANGE( rmesa
, ctx
);
632 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
635 /* Update vertex/render formats
637 if (rmesa
->radeon
.TclFallback
) {
638 radeonChooseRenderState( ctx
);
639 radeonChooseVertexState( ctx
);
644 /* =============================================================
649 /* Update on colormaterial, material emmissive/ambient,
650 * lightmodel.globalambient
652 static void update_global_ambient( struct gl_context
*ctx
)
654 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
655 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
657 /* Need to do more if both emmissive & ambient are PREMULT:
658 * Hope this is not needed for MULT
660 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
661 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
662 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
664 COPY_3V( &fcmd
[GLT_RED
],
665 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
666 ACC_SCALE_3V( &fcmd
[GLT_RED
],
667 ctx
->Light
.Model
.Ambient
,
668 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
672 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
675 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
678 /* Update on change to
682 static void update_light_colors( struct gl_context
*ctx
, GLuint p
)
684 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
686 /* fprintf(stderr, "%s\n", __FUNCTION__); */
689 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
690 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
692 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
693 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
694 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
696 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
700 /* Also fallback for asym colormaterial mode in twoside lighting...
702 static void check_twoside_fallback( struct gl_context
*ctx
)
704 GLboolean fallback
= GL_FALSE
;
707 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
708 if (ctx
->Light
.ColorMaterialEnabled
&&
709 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
710 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
713 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
714 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
715 ctx
->Light
.Material
.Attrib
[i
+1],
716 sizeof(GLfloat
)*4) != 0) {
723 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
727 static void radeonColorMaterial( struct gl_context
*ctx
, GLenum face
, GLenum mode
)
729 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
730 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
732 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
733 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
734 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
735 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
737 if (ctx
->Light
.ColorMaterialEnabled
) {
738 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
740 if (mask
& MAT_BIT_FRONT_EMISSION
) {
741 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
742 RADEON_EMISSIVE_SOURCE_SHIFT
);
745 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
746 RADEON_EMISSIVE_SOURCE_SHIFT
);
749 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
750 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
751 RADEON_AMBIENT_SOURCE_SHIFT
);
754 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
755 RADEON_AMBIENT_SOURCE_SHIFT
);
758 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
759 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
760 RADEON_DIFFUSE_SOURCE_SHIFT
);
763 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
764 RADEON_DIFFUSE_SOURCE_SHIFT
);
767 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
768 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
769 RADEON_SPECULAR_SOURCE_SHIFT
);
772 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
773 RADEON_SPECULAR_SOURCE_SHIFT
);
779 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
780 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
781 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
782 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
785 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
786 RADEON_STATECHANGE( rmesa
, tcl
);
787 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
791 void radeonUpdateMaterial( struct gl_context
*ctx
)
793 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
794 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
795 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
798 if (ctx
->Light
.ColorMaterialEnabled
)
799 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
801 if (RADEON_DEBUG
& RADEON_STATE
)
802 fprintf(stderr
, "%s\n", __FUNCTION__
);
805 if (mask
& MAT_BIT_FRONT_EMISSION
) {
806 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
807 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
808 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
809 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
811 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
812 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
813 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
814 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
815 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
817 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
818 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
819 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
820 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
821 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
823 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
824 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
825 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
826 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
827 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
829 if (mask
& MAT_BIT_FRONT_SHININESS
) {
830 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
833 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
835 check_twoside_fallback( ctx
);
836 /* update_global_ambient( ctx );*/
841 * _MESA_NEW_NEED_EYE_COORDS
843 * Uses derived state from mesa:
852 * which are calculated in light.c and are correct for the current
853 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
854 * and _MESA_NEW_NEED_EYE_COORDS.
856 static void update_light( struct gl_context
*ctx
)
858 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
860 /* Have to check these, or have an automatic shortcircuit mechanism
861 * to remove noop statechanges. (Or just do a better job on the
865 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
867 if (ctx
->_NeedEyeCoords
)
868 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
870 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
873 /* Leave this test disabled: (unexplained q3 lockup) (even with
876 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
878 RADEON_STATECHANGE( rmesa
, tcl
);
879 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
884 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
885 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
886 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
887 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
888 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
889 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
894 if (ctx
->Light
.Enabled
) {
896 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
897 if (ctx
->Light
.Light
[p
].Enabled
) {
898 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
899 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
901 if (l
->EyePosition
[3] == 0.0) {
902 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
903 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
904 fcmd
[LIT_POSITION_W
] = 0;
905 fcmd
[LIT_DIRECTION_W
] = 0;
907 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
908 fcmd
[LIT_DIRECTION_X
] = -l
->_NormSpotDirection
[0];
909 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormSpotDirection
[1];
910 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormSpotDirection
[2];
911 fcmd
[LIT_DIRECTION_W
] = 0;
914 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
920 static void radeonLightfv( struct gl_context
*ctx
, GLenum light
,
921 GLenum pname
, const GLfloat
*params
)
923 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
924 GLint p
= light
- GL_LIGHT0
;
925 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
926 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
933 update_light_colors( ctx
, p
);
936 case GL_SPOT_DIRECTION
:
937 /* picked up in update_light */
941 /* positions picked up in update_light, but can do flag here */
943 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
945 /* FIXME: Set RANGE_ATTEN only when needed */
947 flag
= RADEON_LIGHT_1_IS_LOCAL
;
949 flag
= RADEON_LIGHT_0_IS_LOCAL
;
951 RADEON_STATECHANGE(rmesa
, tcl
);
952 if (l
->EyePosition
[3] != 0.0F
)
953 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
955 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
959 case GL_SPOT_EXPONENT
:
960 RADEON_STATECHANGE(rmesa
, lit
[p
]);
961 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
964 case GL_SPOT_CUTOFF
: {
965 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
966 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
968 RADEON_STATECHANGE(rmesa
, lit
[p
]);
969 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
971 RADEON_STATECHANGE(rmesa
, tcl
);
972 if (l
->SpotCutoff
!= 180.0F
)
973 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
975 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
980 case GL_CONSTANT_ATTENUATION
:
981 RADEON_STATECHANGE(rmesa
, lit
[p
]);
982 fcmd
[LIT_ATTEN_CONST
] = params
[0];
983 if ( params
[0] == 0.0 )
984 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
986 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
988 case GL_LINEAR_ATTENUATION
:
989 RADEON_STATECHANGE(rmesa
, lit
[p
]);
990 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
992 case GL_QUADRATIC_ATTENUATION
:
993 RADEON_STATECHANGE(rmesa
, lit
[p
]);
994 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1000 /* Set RANGE_ATTEN only when needed */
1003 case GL_CONSTANT_ATTENUATION
:
1004 case GL_LINEAR_ATTENUATION
:
1005 case GL_QUADRATIC_ATTENUATION
:
1007 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1008 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1009 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1010 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1011 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1012 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1014 if ( l
->EyePosition
[3] == 0.0F
||
1015 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1016 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1017 /* Disable attenuation */
1018 icmd
[idx
] &= ~atten_flag
;
1020 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1021 /* Enable only constant portion of attenuation calculation */
1022 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1024 /* Enable full attenuation calculation */
1025 icmd
[idx
] &= ~atten_const_flag
;
1026 icmd
[idx
] |= atten_flag
;
1030 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1041 static void radeonLightModelfv( struct gl_context
*ctx
, GLenum pname
,
1042 const GLfloat
*param
)
1044 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1047 case GL_LIGHT_MODEL_AMBIENT
:
1048 update_global_ambient( ctx
);
1051 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1052 RADEON_STATECHANGE( rmesa
, tcl
);
1053 if (ctx
->Light
.Model
.LocalViewer
)
1054 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1056 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1059 case GL_LIGHT_MODEL_TWO_SIDE
:
1060 RADEON_STATECHANGE( rmesa
, tcl
);
1061 if (ctx
->Light
.Model
.TwoSide
)
1062 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1064 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1066 check_twoside_fallback( ctx
);
1068 if (rmesa
->radeon
.TclFallback
) {
1069 radeonChooseRenderState( ctx
);
1070 radeonChooseVertexState( ctx
);
1074 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1075 radeonUpdateSpecular(ctx
);
1083 static void radeonShadeModel( struct gl_context
*ctx
, GLenum mode
)
1085 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1086 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1088 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1089 RADEON_ALPHA_SHADE_MASK
|
1090 RADEON_SPECULAR_SHADE_MASK
|
1091 RADEON_FOG_SHADE_MASK
);
1095 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1096 RADEON_ALPHA_SHADE_FLAT
|
1097 RADEON_SPECULAR_SHADE_FLAT
|
1098 RADEON_FOG_SHADE_FLAT
);
1101 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1102 RADEON_ALPHA_SHADE_GOURAUD
|
1103 RADEON_SPECULAR_SHADE_GOURAUD
|
1104 RADEON_FOG_SHADE_GOURAUD
);
1110 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1111 RADEON_STATECHANGE( rmesa
, set
);
1112 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1117 /* =============================================================
1121 static void radeonClipPlane( struct gl_context
*ctx
, GLenum plane
, const GLfloat
*eq
)
1123 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1124 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1125 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1127 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1128 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1129 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1130 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1131 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1134 static void radeonUpdateClipPlanes( struct gl_context
*ctx
)
1136 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1139 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1140 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1141 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1143 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1144 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1145 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1146 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1147 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1153 /* =============================================================
1158 radeonStencilFuncSeparate( struct gl_context
*ctx
, GLenum face
, GLenum func
,
1159 GLint ref
, GLuint mask
)
1161 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1162 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << RADEON_STENCIL_REF_SHIFT
) |
1163 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1165 RADEON_STATECHANGE( rmesa
, ctx
);
1166 RADEON_STATECHANGE( rmesa
, msk
);
1168 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1169 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1170 RADEON_STENCIL_VALUE_MASK
);
1172 switch ( ctx
->Stencil
.Function
[0] ) {
1174 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1177 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1180 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1183 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1186 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1189 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1192 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1195 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1199 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1203 radeonStencilMaskSeparate( struct gl_context
*ctx
, GLenum face
, GLuint mask
)
1205 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1207 RADEON_STATECHANGE( rmesa
, msk
);
1208 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1209 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1210 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1213 static void radeonStencilOpSeparate( struct gl_context
*ctx
, GLenum face
, GLenum fail
,
1214 GLenum zfail
, GLenum zpass
)
1216 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1218 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1219 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1220 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1222 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1223 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1224 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1225 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1226 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1227 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1229 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1230 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1231 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1232 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1233 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1234 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1235 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1238 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1239 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1240 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1241 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1242 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1243 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1246 RADEON_STATECHANGE( rmesa
, ctx
);
1247 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1248 RADEON_STENCIL_ZFAIL_MASK
|
1249 RADEON_STENCIL_ZPASS_MASK
);
1251 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1253 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1256 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1259 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1262 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1265 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1268 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1271 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1274 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1278 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1280 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1283 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1286 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1289 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1292 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1295 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1298 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1301 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1305 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1307 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1310 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1313 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1316 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1319 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1322 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1325 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1328 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1335 /* =============================================================
1336 * Window position and viewport transformation
1340 * To correctly position primitives:
1342 #define SUBPIXEL_X 0.125
1343 #define SUBPIXEL_Y 0.125
1347 * Called when window size or position changes or viewport or depth range
1348 * state is changed. We update the hardware viewport state here.
1350 void radeonUpdateWindow( struct gl_context
*ctx
)
1352 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1353 __DRIdrawable
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1354 GLfloat xoffset
= 0.0;
1355 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->h
: 0;
1356 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1357 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
? (ctx
->DrawBuffer
->Name
!= 0) : 0);
1358 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1359 GLfloat y_scale
, y_bias
;
1361 if (render_to_fbo
) {
1369 float_ui32_type sx
= { v
[MAT_SX
] };
1370 float_ui32_type tx
= { v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
};
1371 float_ui32_type sy
= { v
[MAT_SY
] * y_scale
};
1372 float_ui32_type ty
= { (v
[MAT_TY
] * y_scale
) + y_bias
+ SUBPIXEL_Y
};
1373 float_ui32_type sz
= { v
[MAT_SZ
] * depthScale
};
1374 float_ui32_type tz
= { v
[MAT_TZ
] * depthScale
};
1376 RADEON_STATECHANGE( rmesa
, vpt
);
1378 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1379 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1380 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1381 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1382 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1383 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1387 static void radeonViewport( struct gl_context
*ctx
, GLint x
, GLint y
,
1388 GLsizei width
, GLsizei height
)
1390 /* Don't pipeline viewport changes, conflict with window offset
1391 * setting below. Could apply deltas to rescue pipelined viewport
1392 * values, or keep the originals hanging around.
1394 radeonUpdateWindow( ctx
);
1396 radeon_viewport(ctx
, x
, y
, width
, height
);
1399 static void radeonDepthRange( struct gl_context
*ctx
, GLclampd nearval
,
1402 radeonUpdateWindow( ctx
);
1405 void radeonUpdateViewportOffset( struct gl_context
*ctx
)
1407 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1408 __DRIdrawable
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1409 GLfloat xoffset
= 0.0;
1410 GLfloat yoffset
= (GLfloat
)dPriv
->h
;
1411 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1416 tx
.f
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1417 ty
.f
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1419 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != tx
.ui32
||
1420 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != ty
.ui32
)
1422 /* Note: this should also modify whatever data the context reset
1425 RADEON_STATECHANGE( rmesa
, vpt
);
1426 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1427 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1429 /* update polygon stipple x/y screen offset */
1432 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1434 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1435 RADEON_STIPPLE_Y_OFFSET_MASK
);
1437 /* add magic offsets, then invert */
1438 stx
= 31 - ((-1) & RADEON_STIPPLE_COORD_MASK
);
1439 sty
= 31 - ((dPriv
->h
- 1)
1440 & RADEON_STIPPLE_COORD_MASK
);
1442 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1443 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1445 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1446 RADEON_STATECHANGE( rmesa
, msc
);
1447 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1452 radeonUpdateScissor( ctx
);
1457 /* =============================================================
1461 static void radeonRenderMode( struct gl_context
*ctx
, GLenum mode
)
1463 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1464 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1468 static GLuint radeon_rop_tab
[] = {
1471 RADEON_ROP_AND_REVERSE
,
1473 RADEON_ROP_AND_INVERTED
,
1480 RADEON_ROP_OR_REVERSE
,
1481 RADEON_ROP_COPY_INVERTED
,
1482 RADEON_ROP_OR_INVERTED
,
1487 static void radeonLogicOpCode( struct gl_context
*ctx
, GLenum opcode
)
1489 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1490 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1494 RADEON_STATECHANGE( rmesa
, msk
);
1495 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1498 /* =============================================================
1499 * State enable/disable
1502 static void radeonEnable( struct gl_context
*ctx
, GLenum cap
, GLboolean state
)
1504 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1507 if ( RADEON_DEBUG
& RADEON_STATE
)
1508 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1509 _mesa_lookup_enum_by_nr( cap
),
1510 state
? "GL_TRUE" : "GL_FALSE" );
1513 /* Fast track this one...
1521 RADEON_STATECHANGE( rmesa
, ctx
);
1523 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1525 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1530 RADEON_STATECHANGE( rmesa
, ctx
);
1532 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1534 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1536 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1537 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1538 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1540 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1543 /* Catch a possible fallback:
1546 ctx
->Driver
.BlendEquationSeparate( ctx
,
1547 ctx
->Color
.Blend
[0].EquationRGB
,
1548 ctx
->Color
.Blend
[0].EquationA
);
1549 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.Blend
[0].SrcRGB
,
1550 ctx
->Color
.Blend
[0].DstRGB
,
1551 ctx
->Color
.Blend
[0].SrcA
,
1552 ctx
->Color
.Blend
[0].DstA
);
1555 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1556 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1560 case GL_CLIP_PLANE0
:
1561 case GL_CLIP_PLANE1
:
1562 case GL_CLIP_PLANE2
:
1563 case GL_CLIP_PLANE3
:
1564 case GL_CLIP_PLANE4
:
1565 case GL_CLIP_PLANE5
:
1566 p
= cap
-GL_CLIP_PLANE0
;
1567 RADEON_STATECHANGE( rmesa
, tcl
);
1569 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1570 radeonClipPlane( ctx
, cap
, NULL
);
1573 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1577 case GL_COLOR_MATERIAL
:
1578 radeonColorMaterial( ctx
, 0, 0 );
1579 radeonUpdateMaterial( ctx
);
1583 radeonCullFace( ctx
, 0 );
1587 RADEON_STATECHANGE(rmesa
, ctx
);
1589 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1591 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1596 RADEON_STATECHANGE(rmesa
, ctx
);
1598 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1599 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->radeon
.state
.color
.roundEnable
;
1601 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1602 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->radeon
.state
.color
.roundEnable
;
1607 RADEON_STATECHANGE(rmesa
, ctx
);
1609 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1610 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1612 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1613 RADEON_STATECHANGE(rmesa
, tcl
);
1614 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1616 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1617 _mesa_allow_light_in_model( ctx
, !state
);
1628 RADEON_STATECHANGE(rmesa
, tcl
);
1629 p
= cap
- GL_LIGHT0
;
1631 flag
= (RADEON_LIGHT_1_ENABLE
|
1632 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1633 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1635 flag
= (RADEON_LIGHT_0_ENABLE
|
1636 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1637 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1640 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1642 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1646 update_light_colors( ctx
, p
);
1650 RADEON_STATECHANGE(rmesa
, tcl
);
1651 radeonUpdateSpecular(ctx
);
1652 check_twoside_fallback( ctx
);
1655 case GL_LINE_SMOOTH
:
1656 RADEON_STATECHANGE( rmesa
, ctx
);
1658 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1660 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1664 case GL_LINE_STIPPLE
:
1665 RADEON_STATECHANGE( rmesa
, ctx
);
1667 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1669 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1673 case GL_COLOR_LOGIC_OP
:
1674 RADEON_STATECHANGE( rmesa
, ctx
);
1675 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1676 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1677 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1679 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1684 RADEON_STATECHANGE( rmesa
, tcl
);
1686 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1688 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1692 case GL_POLYGON_OFFSET_POINT
:
1693 RADEON_STATECHANGE( rmesa
, set
);
1695 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1697 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1701 case GL_POLYGON_OFFSET_LINE
:
1702 RADEON_STATECHANGE( rmesa
, set
);
1704 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1706 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1710 case GL_POLYGON_OFFSET_FILL
:
1711 RADEON_STATECHANGE( rmesa
, set
);
1713 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1715 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1719 case GL_POLYGON_SMOOTH
:
1720 RADEON_STATECHANGE( rmesa
, ctx
);
1722 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1724 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1728 case GL_POLYGON_STIPPLE
:
1729 RADEON_STATECHANGE(rmesa
, ctx
);
1731 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1733 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1737 case GL_RESCALE_NORMAL_EXT
: {
1738 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1739 RADEON_STATECHANGE( rmesa
, tcl
);
1741 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1743 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1748 case GL_SCISSOR_TEST
:
1749 radeon_firevertices(&rmesa
->radeon
);
1750 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1751 radeonUpdateScissor( ctx
);
1754 case GL_STENCIL_TEST
:
1756 GLboolean hw_stencil
= GL_FALSE
;
1757 if (ctx
->DrawBuffer
) {
1758 struct radeon_renderbuffer
*rrbStencil
1759 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
1760 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
1764 RADEON_STATECHANGE( rmesa
, ctx
);
1766 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1768 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1771 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1776 case GL_TEXTURE_GEN_Q
:
1777 case GL_TEXTURE_GEN_R
:
1778 case GL_TEXTURE_GEN_S
:
1779 case GL_TEXTURE_GEN_T
:
1780 /* Picked up in radeonUpdateTextureState.
1782 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1785 case GL_COLOR_SUM_EXT
:
1786 radeonUpdateSpecular ( ctx
);
1795 static void radeonLightingSpaceChange( struct gl_context
*ctx
)
1797 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1799 RADEON_STATECHANGE( rmesa
, tcl
);
1801 if (RADEON_DEBUG
& RADEON_STATE
)
1802 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1803 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1805 if (ctx
->_NeedEyeCoords
)
1806 tmp
= ctx
->Transform
.RescaleNormals
;
1808 tmp
= !ctx
->Transform
.RescaleNormals
;
1811 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1813 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1816 if (RADEON_DEBUG
& RADEON_STATE
)
1817 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1818 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1821 /* =============================================================
1822 * Deferred state management - matrices, textures, other?
1826 void radeonUploadTexMatrix( r100ContextPtr rmesa
,
1827 int unit
, GLboolean swapcols
)
1829 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1830 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1831 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1832 texgen generates all 4 coords, at least tests with projtex indicated that.
1833 So: if we need the q coord in the end (solely determined by the texture
1834 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1835 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1836 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1837 will get submitted in the "wrong", i.e. 3rd, slot.
1838 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1839 size and using the texture matrix to swap the r and q coords around (ut2k3
1840 does exactly that), so we don't need the 3rd / 4th column swap - still need
1841 the 3rd / 4th row swap of course. This will potentially break for apps which
1842 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1843 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1844 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1845 incredibly hard to detect so we can't just fallback in such a case. Assume
1846 it never happens... - rs
1849 int idx
= TEXMAT_0
+ unit
;
1850 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
1852 struct gl_texture_unit tUnit
= rmesa
->radeon
.glCtx
->Texture
.Unit
[unit
];
1853 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
1855 rmesa
->TexMatColSwap
&= ~(1 << unit
);
1856 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
1858 rmesa
->TexMatColSwap
|= 1 << unit
;
1859 /* attention some elems are swapped 2 times! */
1872 /* those last 4 are probably never used */
1879 for (i
= 0; i
< 2; i
++) {
1883 *dest
++ = src
[i
+12];
1885 for (i
= 3; i
>= 2; i
--) {
1889 *dest
++ = src
[i
+12];
1894 for (i
= 0 ; i
< 4 ; i
++) {
1898 *dest
++ = src
[i
+12];
1902 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1906 static void upload_matrix( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1908 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1912 for (i
= 0 ; i
< 4 ; i
++) {
1916 *dest
++ = src
[i
+12];
1919 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1922 static void upload_matrix_t( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1924 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1925 memcpy(dest
, src
, 16*sizeof(float));
1926 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1930 static void update_texturematrix( struct gl_context
*ctx
)
1932 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
1933 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
1934 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
1936 GLuint texMatEnabled
= 0;
1937 rmesa
->NeedTexMatrix
= 0;
1938 rmesa
->TexMatColSwap
= 0;
1940 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
1941 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
1942 GLboolean needMatrix
= GL_FALSE
;
1943 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
1944 needMatrix
= GL_TRUE
;
1945 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
1946 RADEON_TEXMAT_0_ENABLE
) << unit
;
1948 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1949 /* Need to preconcatenate any active texgen
1950 * obj/eyeplane matrices:
1952 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
1953 ctx
->TextureMatrixStack
[unit
].Top
,
1954 &rmesa
->TexGenMatrix
[unit
] );
1957 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
1958 ctx
->TextureMatrixStack
[unit
].Top
);
1961 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1962 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
1963 needMatrix
= GL_TRUE
;
1966 rmesa
->NeedTexMatrix
|= 1 << unit
;
1967 radeonUploadTexMatrix( rmesa
, unit
,
1968 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
1973 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
1975 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1976 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
1977 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
1978 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
1980 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
1981 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
1982 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
1983 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
1984 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
1985 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
1987 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
1988 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
1990 RADEON_STATECHANGE(rmesa
, tcl
);
1991 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
1992 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
1996 static GLboolean
r100ValidateBuffers(struct gl_context
*ctx
)
1998 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1999 struct radeon_renderbuffer
*rrb
;
2002 radeon_cs_space_reset_bos(rmesa
->radeon
.cmdbuf
.cs
);
2004 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
2006 if (rrb
&& rrb
->bo
) {
2007 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
2008 0, RADEON_GEM_DOMAIN_VRAM
);
2012 rrb
= radeon_get_depthbuffer(&rmesa
->radeon
);
2014 if (rrb
&& rrb
->bo
) {
2015 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
2016 0, RADEON_GEM_DOMAIN_VRAM
);
2019 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; ++i
) {
2022 if (!ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2025 t
= rmesa
->state
.texture
.unit
[i
].texobj
;
2029 if (t
->image_override
&& t
->bo
)
2030 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->bo
,
2031 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
2033 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->mt
->bo
,
2034 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
2037 ret
= radeon_cs_space_check_with_bo(rmesa
->radeon
.cmdbuf
.cs
, first_elem(&rmesa
->radeon
.dma
.reserved
)->bo
, RADEON_GEM_DOMAIN_GTT
, 0);
2043 GLboolean
radeonValidateState( struct gl_context
*ctx
)
2045 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2046 GLuint new_state
= rmesa
->radeon
.NewGLState
;
2048 if (new_state
& _NEW_BUFFERS
) {
2049 _mesa_update_framebuffer(ctx
);
2050 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2051 _mesa_update_draw_buffer_bounds(ctx
);
2052 RADEON_STATECHANGE(rmesa
, ctx
);
2055 if (new_state
& _NEW_TEXTURE
) {
2056 radeonUpdateTextureState( ctx
);
2057 new_state
|= rmesa
->radeon
.NewGLState
; /* may add TEXTURE_MATRIX */
2060 /* we need to do a space check here */
2061 if (!r100ValidateBuffers(ctx
))
2064 /* Need an event driven matrix update?
2066 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2067 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2069 /* Need these for lighting (shouldn't upload otherwise)
2071 if (new_state
& (_NEW_MODELVIEW
)) {
2072 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2073 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2076 /* Does this need to be triggered on eg. modelview for
2077 * texgen-derived objplane/eyeplane matrices?
2079 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2080 update_texturematrix( ctx
);
2083 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2084 update_light( ctx
);
2087 /* emit all active clip planes if projection matrix changes.
2089 if (new_state
& (_NEW_PROJECTION
)) {
2090 if (ctx
->Transform
.ClipPlanesEnabled
)
2091 radeonUpdateClipPlanes( ctx
);
2095 rmesa
->radeon
.NewGLState
= 0;
2101 static void radeonInvalidateState( struct gl_context
*ctx
, GLuint new_state
)
2103 _swrast_InvalidateState( ctx
, new_state
);
2104 _swsetup_InvalidateState( ctx
, new_state
);
2105 _vbo_InvalidateState( ctx
, new_state
);
2106 _tnl_InvalidateState( ctx
, new_state
);
2107 _ae_invalidate_state( ctx
, new_state
);
2108 R100_CONTEXT(ctx
)->radeon
.NewGLState
|= new_state
;
2112 /* A hack. Need a faster way to find this out.
2114 static GLboolean
check_material( struct gl_context
*ctx
)
2116 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2119 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2120 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2122 if (tnl
->vb
.AttribPtr
[i
] &&
2123 tnl
->vb
.AttribPtr
[i
]->stride
)
2130 static void radeonWrapRunPipeline( struct gl_context
*ctx
)
2132 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2133 GLboolean has_material
;
2136 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->radeon
.NewGLState
);
2140 if (rmesa
->radeon
.NewGLState
)
2141 if (!radeonValidateState( ctx
))
2142 FALLBACK(rmesa
, RADEON_FALLBACK_TEXTURE
, GL_TRUE
);
2144 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2147 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2150 /* Run the pipeline.
2152 _tnl_run_pipeline( ctx
);
2155 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2159 static void radeonPolygonStipple( struct gl_context
*ctx
, const GLubyte
*mask
)
2161 r100ContextPtr r100
= R100_CONTEXT(ctx
);
2164 radeon_firevertices(&r100
->radeon
);
2166 RADEON_STATECHANGE(r100
, stp
);
2168 /* Must flip pattern upside down.
2170 for ( i
= 31 ; i
>= 0; i
--) {
2171 r100
->hw
.stp
.cmd
[3 + i
] = ((GLuint
*) mask
)[i
];
2176 /* Initialize the driver's state functions.
2177 * Many of the ctx->Driver functions might have been initialized to
2178 * software defaults in the earlier _mesa_init_driver_functions() call.
2180 void radeonInitStateFuncs( struct gl_context
*ctx
)
2182 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2183 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2185 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2186 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2187 ctx
->Driver
.CopyPixels
= _mesa_meta_CopyPixels
;
2188 ctx
->Driver
.DrawPixels
= _mesa_meta_DrawPixels
;
2189 ctx
->Driver
.ReadPixels
= radeonReadPixels
;
2191 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2192 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2193 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2194 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2195 ctx
->Driver
.ColorMask
= radeonColorMask
;
2196 ctx
->Driver
.CullFace
= radeonCullFace
;
2197 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2198 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2199 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2200 ctx
->Driver
.Enable
= radeonEnable
;
2201 ctx
->Driver
.Fogfv
= radeonFogfv
;
2202 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2203 ctx
->Driver
.Hint
= NULL
;
2204 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2205 ctx
->Driver
.Lightfv
= radeonLightfv
;
2206 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2207 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2208 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2209 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2210 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2211 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2212 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2213 ctx
->Driver
.Scissor
= radeonScissor
;
2214 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2215 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2216 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2217 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2218 ctx
->Driver
.Viewport
= radeonViewport
;
2220 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2221 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;