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/fbobject.h"
43 #include "main/simple_list.h"
44 #include "main/state.h"
48 #include "tnl/t_pipeline.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "drivers/common/meta.h"
52 #include "radeon_context.h"
53 #include "radeon_mipmap_tree.h"
54 #include "radeon_ioctl.h"
55 #include "radeon_state.h"
56 #include "radeon_tcl.h"
57 #include "radeon_tex.h"
58 #include "radeon_swtcl.h"
60 static void radeonUpdateSpecular( struct gl_context
*ctx
);
62 /* =============================================================
66 static void radeonAlphaFunc( struct gl_context
*ctx
, GLenum func
, GLfloat ref
)
68 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
69 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
72 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
74 RADEON_STATECHANGE( rmesa
, ctx
);
76 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
77 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
81 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
84 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
87 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
90 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
93 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
96 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
99 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
102 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
106 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
109 static void radeonBlendEquationSeparate( struct gl_context
*ctx
,
110 GLenum modeRGB
, GLenum modeA
)
112 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
113 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
114 GLboolean fallback
= GL_FALSE
;
116 assert( modeRGB
== modeA
);
121 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
124 case GL_FUNC_SUBTRACT
:
125 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
129 if (ctx
->Color
.BlendEnabled
)
132 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
136 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
138 RADEON_STATECHANGE( rmesa
, ctx
);
139 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
140 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
141 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
142 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
144 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
149 static void radeonBlendFuncSeparate( struct gl_context
*ctx
,
150 GLenum sfactorRGB
, GLenum dfactorRGB
,
151 GLenum sfactorA
, GLenum dfactorA
)
153 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
154 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
155 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
156 GLboolean fallback
= GL_FALSE
;
158 switch ( ctx
->Color
.Blend
[0].SrcRGB
) {
160 b
|= RADEON_SRC_BLEND_GL_ZERO
;
163 b
|= RADEON_SRC_BLEND_GL_ONE
;
166 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
168 case GL_ONE_MINUS_DST_COLOR
:
169 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
172 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
174 case GL_ONE_MINUS_SRC_COLOR
:
175 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
178 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
180 case GL_ONE_MINUS_SRC_ALPHA
:
181 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
184 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
186 case GL_ONE_MINUS_DST_ALPHA
:
187 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
189 case GL_SRC_ALPHA_SATURATE
:
190 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
192 case GL_CONSTANT_COLOR
:
193 case GL_ONE_MINUS_CONSTANT_COLOR
:
194 case GL_CONSTANT_ALPHA
:
195 case GL_ONE_MINUS_CONSTANT_ALPHA
:
196 if (ctx
->Color
.BlendEnabled
)
199 b
|= RADEON_SRC_BLEND_GL_ONE
;
205 switch ( ctx
->Color
.Blend
[0].DstRGB
) {
207 b
|= RADEON_DST_BLEND_GL_ZERO
;
210 b
|= RADEON_DST_BLEND_GL_ONE
;
213 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
215 case GL_ONE_MINUS_SRC_COLOR
:
216 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
219 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
221 case GL_ONE_MINUS_SRC_ALPHA
:
222 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
225 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
227 case GL_ONE_MINUS_DST_COLOR
:
228 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
231 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
233 case GL_ONE_MINUS_DST_ALPHA
:
234 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
236 case GL_CONSTANT_COLOR
:
237 case GL_ONE_MINUS_CONSTANT_COLOR
:
238 case GL_CONSTANT_ALPHA
:
239 case GL_ONE_MINUS_CONSTANT_ALPHA
:
240 if (ctx
->Color
.BlendEnabled
)
243 b
|= RADEON_DST_BLEND_GL_ZERO
;
249 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
251 RADEON_STATECHANGE( rmesa
, ctx
);
252 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
257 /* =============================================================
261 static void radeonDepthFunc( struct gl_context
*ctx
, GLenum func
)
263 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
265 RADEON_STATECHANGE( rmesa
, ctx
);
266 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
268 switch ( ctx
->Depth
.Func
) {
270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
291 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
297 static void radeonDepthMask( struct gl_context
*ctx
, GLboolean flag
)
299 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
300 RADEON_STATECHANGE( rmesa
, ctx
);
302 if ( ctx
->Depth
.Mask
) {
303 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
305 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
310 /* =============================================================
315 static void radeonFogfv( struct gl_context
*ctx
, GLenum pname
, const GLfloat
*param
)
317 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
318 union { int i
; float f
; } c
, d
;
323 if (!ctx
->Fog
.Enabled
)
325 RADEON_STATECHANGE(rmesa
, tcl
);
326 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
327 switch (ctx
->Fog
.Mode
) {
329 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
332 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
335 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
344 if (!ctx
->Fog
.Enabled
)
346 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
347 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
348 switch (ctx
->Fog
.Mode
) {
351 /* While this is the opposite sign from the DDK, it makes the fog test
352 * pass, and matches r200.
354 d
.f
= -ctx
->Fog
.Density
;
358 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
361 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
365 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
366 /* While this is the opposite sign from the DDK, it makes the fog
367 * test pass, and matches r200.
369 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
375 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
376 RADEON_STATECHANGE( rmesa
, fog
);
377 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
378 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
382 RADEON_STATECHANGE( rmesa
, ctx
);
383 _mesa_unclamped_float_rgba_to_ubyte(col
, ctx
->Fog
.Color
);
384 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
385 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
386 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
388 case GL_FOG_COORD_SRC
:
389 radeonUpdateSpecular( ctx
);
396 /* =============================================================
400 static void radeonCullFace( struct gl_context
*ctx
, GLenum unused
)
402 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
403 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
404 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
406 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
407 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
409 if ( ctx
->Polygon
.CullFlag
) {
410 switch ( ctx
->Polygon
.CullFaceMode
) {
412 s
&= ~RADEON_FFACE_SOLID
;
413 t
|= RADEON_CULL_FRONT
;
416 s
&= ~RADEON_BFACE_SOLID
;
417 t
|= RADEON_CULL_BACK
;
419 case GL_FRONT_AND_BACK
:
420 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
421 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
426 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
427 RADEON_STATECHANGE(rmesa
, set
);
428 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
431 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
432 RADEON_STATECHANGE(rmesa
, tcl
);
433 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
437 static void radeonFrontFace( struct gl_context
*ctx
, GLenum mode
)
439 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
440 int cull_face
= (mode
== GL_CW
) ? RADEON_FFACE_CULL_CW
: RADEON_FFACE_CULL_CCW
;
442 RADEON_STATECHANGE( rmesa
, set
);
443 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
445 RADEON_STATECHANGE( rmesa
, tcl
);
446 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
448 /* Winding is inverted when rendering to FBO */
449 if (ctx
->DrawBuffer
&& _mesa_is_user_fbo(ctx
->DrawBuffer
))
450 cull_face
= (mode
== GL_CCW
) ? RADEON_FFACE_CULL_CW
: RADEON_FFACE_CULL_CCW
;
451 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= cull_face
;
453 if ( mode
== GL_CCW
)
454 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
458 /* =============================================================
461 static void radeonLineWidth( struct gl_context
*ctx
, GLfloat widthf
)
463 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
465 RADEON_STATECHANGE( rmesa
, lin
);
466 RADEON_STATECHANGE( rmesa
, set
);
468 /* Line width is stored in U6.4 format.
470 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
471 if ( widthf
> 1.0 ) {
472 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
474 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
478 static void radeonLineStipple( struct gl_context
*ctx
, GLint factor
, GLushort pattern
)
480 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
482 RADEON_STATECHANGE( rmesa
, lin
);
483 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
484 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
488 /* =============================================================
491 static void radeonColorMask( struct gl_context
*ctx
,
492 GLboolean r
, GLboolean g
,
493 GLboolean b
, GLboolean a
)
495 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
496 struct radeon_renderbuffer
*rrb
;
499 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
503 mask
= radeonPackColor( rrb
->cpp
,
504 ctx
->Color
.ColorMask
[0][RCOMP
],
505 ctx
->Color
.ColorMask
[0][GCOMP
],
506 ctx
->Color
.ColorMask
[0][BCOMP
],
507 ctx
->Color
.ColorMask
[0][ACOMP
] );
509 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
510 RADEON_STATECHANGE( rmesa
, msk
);
511 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
516 /* =============================================================
520 static void radeonPolygonOffset( struct gl_context
*ctx
,
521 GLfloat factor
, GLfloat units
)
523 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
524 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
525 float_ui32_type constant
= { units
* depthScale
};
526 float_ui32_type factoru
= { factor
};
528 RADEON_STATECHANGE( rmesa
, zbs
);
529 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
530 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
533 static void radeonPolygonMode( struct gl_context
*ctx
, GLenum face
, GLenum mode
)
535 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
536 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
538 /* Can't generally do unfilled via tcl, but some good special
541 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
542 if (rmesa
->radeon
.TclFallback
) {
543 radeonChooseRenderState( ctx
);
544 radeonChooseVertexState( ctx
);
549 /* =============================================================
550 * Rendering attributes
552 * We really don't want to recalculate all this every time we bind a
553 * texture. These things shouldn't change all that often, so it makes
554 * sense to break them out of the core texture state update routines.
557 /* Examine lighting and texture state to determine if separate specular
560 static void radeonUpdateSpecular( struct gl_context
*ctx
)
562 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
563 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
566 RADEON_STATECHANGE( rmesa
, tcl
);
568 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
569 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
570 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
571 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
572 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
574 p
&= ~RADEON_SPECULAR_ENABLE
;
576 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
579 if (ctx
->Light
.Enabled
&&
580 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
581 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
582 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
583 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
584 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
585 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
586 p
|= RADEON_SPECULAR_ENABLE
;
587 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
588 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
590 else if (ctx
->Light
.Enabled
) {
591 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
592 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
593 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
594 } else if (ctx
->Fog
.ColorSumEnabled
) {
595 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
596 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
597 p
|= RADEON_SPECULAR_ENABLE
;
599 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
602 if (ctx
->Fog
.Enabled
) {
603 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
604 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
605 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
606 /* Bizzare: have to leave lighting enabled to get fog. */
607 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
610 /* cannot do tcl fog factor calculation with fog coord source
611 * (send precomputed factors). Cannot use precomputed fog
612 * factors together with tcl spec light (need tcl fallback) */
613 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
614 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
618 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
620 if (_mesa_need_secondary_color(ctx
)) {
621 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
623 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
626 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
627 RADEON_STATECHANGE( rmesa
, ctx
);
628 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
631 /* Update vertex/render formats
633 if (rmesa
->radeon
.TclFallback
) {
634 radeonChooseRenderState( ctx
);
635 radeonChooseVertexState( ctx
);
640 /* =============================================================
645 /* Update on colormaterial, material emmissive/ambient,
646 * lightmodel.globalambient
648 static void update_global_ambient( struct gl_context
*ctx
)
650 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
651 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
653 /* Need to do more if both emmissive & ambient are PREMULT:
654 * Hope this is not needed for MULT
656 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
657 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
658 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
660 COPY_3V( &fcmd
[GLT_RED
],
661 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
662 ACC_SCALE_3V( &fcmd
[GLT_RED
],
663 ctx
->Light
.Model
.Ambient
,
664 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
668 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
671 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
674 /* Update on change to
678 static void update_light_colors( struct gl_context
*ctx
, GLuint p
)
680 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
682 /* fprintf(stderr, "%s\n", __FUNCTION__); */
685 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
686 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
688 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
689 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
690 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
692 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
696 /* Also fallback for asym colormaterial mode in twoside lighting...
698 static void check_twoside_fallback( struct gl_context
*ctx
)
700 GLboolean fallback
= GL_FALSE
;
703 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
704 if (ctx
->Light
.ColorMaterialEnabled
&&
705 (ctx
->Light
._ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
706 ((ctx
->Light
._ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
709 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
710 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
711 ctx
->Light
.Material
.Attrib
[i
+1],
712 sizeof(GLfloat
)*4) != 0) {
719 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
723 static void radeonColorMaterial( struct gl_context
*ctx
, GLenum face
, GLenum mode
)
725 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
726 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
728 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
729 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
730 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
731 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
733 if (ctx
->Light
.ColorMaterialEnabled
) {
734 GLuint mask
= ctx
->Light
._ColorMaterialBitmask
;
736 if (mask
& MAT_BIT_FRONT_EMISSION
) {
737 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
738 RADEON_EMISSIVE_SOURCE_SHIFT
);
741 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
742 RADEON_EMISSIVE_SOURCE_SHIFT
);
745 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
746 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
747 RADEON_AMBIENT_SOURCE_SHIFT
);
750 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
751 RADEON_AMBIENT_SOURCE_SHIFT
);
754 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
755 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
756 RADEON_DIFFUSE_SOURCE_SHIFT
);
759 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
760 RADEON_DIFFUSE_SOURCE_SHIFT
);
763 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
764 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
765 RADEON_SPECULAR_SOURCE_SHIFT
);
768 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
769 RADEON_SPECULAR_SOURCE_SHIFT
);
775 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
776 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
777 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
778 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
781 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
782 RADEON_STATECHANGE( rmesa
, tcl
);
783 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
787 void radeonUpdateMaterial( struct gl_context
*ctx
)
789 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
790 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
791 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
794 if (ctx
->Light
.ColorMaterialEnabled
)
795 mask
&= ~ctx
->Light
._ColorMaterialBitmask
;
797 if (RADEON_DEBUG
& RADEON_STATE
)
798 fprintf(stderr
, "%s\n", __FUNCTION__
);
801 if (mask
& MAT_BIT_FRONT_EMISSION
) {
802 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
803 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
804 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
805 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
807 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
808 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
809 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
810 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
811 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
813 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
814 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
815 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
816 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
817 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
819 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
820 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
821 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
822 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
823 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
825 if (mask
& MAT_BIT_FRONT_SHININESS
) {
826 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
829 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
831 check_twoside_fallback( ctx
);
832 /* update_global_ambient( ctx );*/
837 * _MESA_NEW_NEED_EYE_COORDS
839 * Uses derived state from mesa:
848 * which are calculated in light.c and are correct for the current
849 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
850 * and _MESA_NEW_NEED_EYE_COORDS.
852 static void update_light( struct gl_context
*ctx
)
854 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
856 /* Have to check these, or have an automatic shortcircuit mechanism
857 * to remove noop statechanges. (Or just do a better job on the
861 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
863 if (ctx
->_NeedEyeCoords
)
864 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
866 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
869 /* Leave this test disabled: (unexplained q3 lockup) (even with
872 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
874 RADEON_STATECHANGE( rmesa
, tcl
);
875 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
880 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
881 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
882 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
883 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
884 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
885 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
890 if (ctx
->Light
.Enabled
) {
892 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
893 if (ctx
->Light
.Light
[p
].Enabled
) {
894 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
895 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
897 if (l
->EyePosition
[3] == 0.0) {
898 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
899 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
900 fcmd
[LIT_POSITION_W
] = 0;
901 fcmd
[LIT_DIRECTION_W
] = 0;
903 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
904 fcmd
[LIT_DIRECTION_X
] = -l
->_NormSpotDirection
[0];
905 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormSpotDirection
[1];
906 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormSpotDirection
[2];
907 fcmd
[LIT_DIRECTION_W
] = 0;
910 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
916 static void radeonLightfv( struct gl_context
*ctx
, GLenum light
,
917 GLenum pname
, const GLfloat
*params
)
919 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
920 GLint p
= light
- GL_LIGHT0
;
921 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
922 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
929 update_light_colors( ctx
, p
);
932 case GL_SPOT_DIRECTION
:
933 /* picked up in update_light */
937 /* positions picked up in update_light, but can do flag here */
939 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
941 /* FIXME: Set RANGE_ATTEN only when needed */
943 flag
= RADEON_LIGHT_1_IS_LOCAL
;
945 flag
= RADEON_LIGHT_0_IS_LOCAL
;
947 RADEON_STATECHANGE(rmesa
, tcl
);
948 if (l
->EyePosition
[3] != 0.0F
)
949 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
951 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
955 case GL_SPOT_EXPONENT
:
956 RADEON_STATECHANGE(rmesa
, lit
[p
]);
957 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
960 case GL_SPOT_CUTOFF
: {
961 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
962 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
964 RADEON_STATECHANGE(rmesa
, lit
[p
]);
965 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
967 RADEON_STATECHANGE(rmesa
, tcl
);
968 if (l
->SpotCutoff
!= 180.0F
)
969 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
971 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
976 case GL_CONSTANT_ATTENUATION
:
977 RADEON_STATECHANGE(rmesa
, lit
[p
]);
978 fcmd
[LIT_ATTEN_CONST
] = params
[0];
979 if ( params
[0] == 0.0 )
980 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
982 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
984 case GL_LINEAR_ATTENUATION
:
985 RADEON_STATECHANGE(rmesa
, lit
[p
]);
986 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
988 case GL_QUADRATIC_ATTENUATION
:
989 RADEON_STATECHANGE(rmesa
, lit
[p
]);
990 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
996 /* Set RANGE_ATTEN only when needed */
999 case GL_CONSTANT_ATTENUATION
:
1000 case GL_LINEAR_ATTENUATION
:
1001 case GL_QUADRATIC_ATTENUATION
:
1003 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1004 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1005 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1006 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1007 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1008 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1010 if ( l
->EyePosition
[3] == 0.0F
||
1011 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1012 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1013 /* Disable attenuation */
1014 icmd
[idx
] &= ~atten_flag
;
1016 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1017 /* Enable only constant portion of attenuation calculation */
1018 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1020 /* Enable full attenuation calculation */
1021 icmd
[idx
] &= ~atten_const_flag
;
1022 icmd
[idx
] |= atten_flag
;
1026 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1037 static void radeonLightModelfv( struct gl_context
*ctx
, GLenum pname
,
1038 const GLfloat
*param
)
1040 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1043 case GL_LIGHT_MODEL_AMBIENT
:
1044 update_global_ambient( ctx
);
1047 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1048 RADEON_STATECHANGE( rmesa
, tcl
);
1049 if (ctx
->Light
.Model
.LocalViewer
)
1050 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1052 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1055 case GL_LIGHT_MODEL_TWO_SIDE
:
1056 RADEON_STATECHANGE( rmesa
, tcl
);
1057 if (ctx
->Light
.Model
.TwoSide
)
1058 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1060 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1062 check_twoside_fallback( ctx
);
1064 if (rmesa
->radeon
.TclFallback
) {
1065 radeonChooseRenderState( ctx
);
1066 radeonChooseVertexState( ctx
);
1070 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1071 radeonUpdateSpecular(ctx
);
1079 static void radeonShadeModel( struct gl_context
*ctx
, GLenum mode
)
1081 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1082 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1084 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1085 RADEON_ALPHA_SHADE_MASK
|
1086 RADEON_SPECULAR_SHADE_MASK
|
1087 RADEON_FOG_SHADE_MASK
);
1091 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1092 RADEON_ALPHA_SHADE_FLAT
|
1093 RADEON_SPECULAR_SHADE_FLAT
|
1094 RADEON_FOG_SHADE_FLAT
);
1097 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1098 RADEON_ALPHA_SHADE_GOURAUD
|
1099 RADEON_SPECULAR_SHADE_GOURAUD
|
1100 RADEON_FOG_SHADE_GOURAUD
);
1106 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1107 RADEON_STATECHANGE( rmesa
, set
);
1108 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1113 /* =============================================================
1117 static void radeonClipPlane( struct gl_context
*ctx
, GLenum plane
, const GLfloat
*eq
)
1119 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1120 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1121 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1123 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1124 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1125 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1126 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1127 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1130 static void radeonUpdateClipPlanes( struct gl_context
*ctx
)
1132 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1135 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1136 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1137 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1139 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1140 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1141 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1142 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1143 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1149 /* =============================================================
1154 radeonStencilFuncSeparate( struct gl_context
*ctx
, GLenum face
, GLenum func
,
1155 GLint ref
, GLuint mask
)
1157 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1158 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << RADEON_STENCIL_REF_SHIFT
) |
1159 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1161 RADEON_STATECHANGE( rmesa
, ctx
);
1162 RADEON_STATECHANGE( rmesa
, msk
);
1164 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1165 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1166 RADEON_STENCIL_VALUE_MASK
);
1168 switch ( ctx
->Stencil
.Function
[0] ) {
1170 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1173 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1176 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1179 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1182 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1185 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1188 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1191 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1195 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1199 radeonStencilMaskSeparate( struct gl_context
*ctx
, GLenum face
, GLuint mask
)
1201 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1203 RADEON_STATECHANGE( rmesa
, msk
);
1204 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1205 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1206 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1209 static void radeonStencilOpSeparate( struct gl_context
*ctx
, GLenum face
, GLenum fail
,
1210 GLenum zfail
, GLenum zpass
)
1212 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1214 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1215 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1216 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1218 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1219 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1220 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1221 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1222 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1223 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1225 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1226 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1227 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1228 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1229 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1230 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1231 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1234 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1235 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1236 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1237 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1238 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1239 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1242 RADEON_STATECHANGE( rmesa
, ctx
);
1243 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1244 RADEON_STENCIL_ZFAIL_MASK
|
1245 RADEON_STENCIL_ZPASS_MASK
);
1247 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1249 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1252 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1255 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1258 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1261 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1264 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1267 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1274 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1291 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1294 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1297 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1301 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1303 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1306 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1309 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1312 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1315 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1318 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1321 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1324 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1331 /* =============================================================
1332 * Window position and viewport transformation
1336 * To correctly position primitives:
1338 #define SUBPIXEL_X 0.125
1339 #define SUBPIXEL_Y 0.125
1343 * Called when window size or position changes or viewport or depth range
1344 * state is changed. We update the hardware viewport state here.
1346 void radeonUpdateWindow( struct gl_context
*ctx
)
1348 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1349 __DRIdrawable
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1350 GLfloat xoffset
= 0.0;
1351 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->h
: 0;
1352 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1353 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
? _mesa_is_user_fbo(ctx
->DrawBuffer
) : 0);
1354 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1355 GLfloat y_scale
, y_bias
;
1357 if (render_to_fbo
) {
1365 float_ui32_type sx
= { v
[MAT_SX
] };
1366 float_ui32_type tx
= { v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
};
1367 float_ui32_type sy
= { v
[MAT_SY
] * y_scale
};
1368 float_ui32_type ty
= { (v
[MAT_TY
] * y_scale
) + y_bias
+ SUBPIXEL_Y
};
1369 float_ui32_type sz
= { v
[MAT_SZ
] * depthScale
};
1370 float_ui32_type tz
= { v
[MAT_TZ
] * depthScale
};
1372 RADEON_STATECHANGE( rmesa
, vpt
);
1374 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1375 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1376 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1377 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1378 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1379 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1383 static void radeonViewport( struct gl_context
*ctx
, GLint x
, GLint y
,
1384 GLsizei width
, GLsizei height
)
1386 /* Don't pipeline viewport changes, conflict with window offset
1387 * setting below. Could apply deltas to rescue pipelined viewport
1388 * values, or keep the originals hanging around.
1390 radeonUpdateWindow( ctx
);
1392 radeon_viewport(ctx
, x
, y
, width
, height
);
1395 static void radeonDepthRange( struct gl_context
*ctx
, GLclampd nearval
,
1398 radeonUpdateWindow( ctx
);
1401 void radeonUpdateViewportOffset( struct gl_context
*ctx
)
1403 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1404 __DRIdrawable
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1405 GLfloat xoffset
= 0.0;
1406 GLfloat yoffset
= (GLfloat
)dPriv
->h
;
1407 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1412 tx
.f
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1413 ty
.f
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1415 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != tx
.ui32
||
1416 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != ty
.ui32
)
1418 /* Note: this should also modify whatever data the context reset
1421 RADEON_STATECHANGE( rmesa
, vpt
);
1422 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1423 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1425 /* update polygon stipple x/y screen offset */
1428 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1430 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1431 RADEON_STIPPLE_Y_OFFSET_MASK
);
1433 /* add magic offsets, then invert */
1434 stx
= 31 - ((-1) & RADEON_STIPPLE_COORD_MASK
);
1435 sty
= 31 - ((dPriv
->h
- 1)
1436 & RADEON_STIPPLE_COORD_MASK
);
1438 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1439 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1441 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1442 RADEON_STATECHANGE( rmesa
, msc
);
1443 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1448 radeonUpdateScissor( ctx
);
1453 /* =============================================================
1457 static void radeonRenderMode( struct gl_context
*ctx
, GLenum mode
)
1459 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1460 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1464 static GLuint radeon_rop_tab
[] = {
1467 RADEON_ROP_AND_REVERSE
,
1469 RADEON_ROP_AND_INVERTED
,
1476 RADEON_ROP_OR_REVERSE
,
1477 RADEON_ROP_COPY_INVERTED
,
1478 RADEON_ROP_OR_INVERTED
,
1483 static void radeonLogicOpCode( struct gl_context
*ctx
, GLenum opcode
)
1485 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1486 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1490 RADEON_STATECHANGE( rmesa
, msk
);
1491 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1494 /* =============================================================
1495 * State enable/disable
1498 static void radeonEnable( struct gl_context
*ctx
, GLenum cap
, GLboolean state
)
1500 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1503 if ( RADEON_DEBUG
& RADEON_STATE
)
1504 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1505 _mesa_lookup_enum_by_nr( cap
),
1506 state
? "GL_TRUE" : "GL_FALSE" );
1509 /* Fast track this one...
1517 RADEON_STATECHANGE( rmesa
, ctx
);
1519 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1521 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1526 RADEON_STATECHANGE( rmesa
, ctx
);
1528 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1530 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1532 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1533 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1534 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1536 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1539 /* Catch a possible fallback:
1542 ctx
->Driver
.BlendEquationSeparate( ctx
,
1543 ctx
->Color
.Blend
[0].EquationRGB
,
1544 ctx
->Color
.Blend
[0].EquationA
);
1545 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.Blend
[0].SrcRGB
,
1546 ctx
->Color
.Blend
[0].DstRGB
,
1547 ctx
->Color
.Blend
[0].SrcA
,
1548 ctx
->Color
.Blend
[0].DstA
);
1551 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1552 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1556 case GL_CLIP_PLANE0
:
1557 case GL_CLIP_PLANE1
:
1558 case GL_CLIP_PLANE2
:
1559 case GL_CLIP_PLANE3
:
1560 case GL_CLIP_PLANE4
:
1561 case GL_CLIP_PLANE5
:
1562 p
= cap
-GL_CLIP_PLANE0
;
1563 RADEON_STATECHANGE( rmesa
, tcl
);
1565 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1566 radeonClipPlane( ctx
, cap
, NULL
);
1569 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1573 case GL_COLOR_MATERIAL
:
1574 radeonColorMaterial( ctx
, 0, 0 );
1575 radeonUpdateMaterial( ctx
);
1579 radeonCullFace( ctx
, 0 );
1583 RADEON_STATECHANGE(rmesa
, ctx
);
1585 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1587 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1592 RADEON_STATECHANGE(rmesa
, ctx
);
1594 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1595 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->radeon
.state
.color
.roundEnable
;
1597 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1598 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->radeon
.state
.color
.roundEnable
;
1603 RADEON_STATECHANGE(rmesa
, ctx
);
1605 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1606 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1608 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1609 RADEON_STATECHANGE(rmesa
, tcl
);
1610 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1612 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1613 _mesa_allow_light_in_model( ctx
, !state
);
1624 RADEON_STATECHANGE(rmesa
, tcl
);
1625 p
= cap
- GL_LIGHT0
;
1627 flag
= (RADEON_LIGHT_1_ENABLE
|
1628 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1629 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1631 flag
= (RADEON_LIGHT_0_ENABLE
|
1632 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1633 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1636 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1638 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1642 update_light_colors( ctx
, p
);
1646 RADEON_STATECHANGE(rmesa
, tcl
);
1647 radeonUpdateSpecular(ctx
);
1648 check_twoside_fallback( ctx
);
1651 case GL_LINE_SMOOTH
:
1652 RADEON_STATECHANGE( rmesa
, ctx
);
1654 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1656 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1660 case GL_LINE_STIPPLE
:
1661 RADEON_STATECHANGE( rmesa
, ctx
);
1663 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1665 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1669 case GL_COLOR_LOGIC_OP
:
1670 RADEON_STATECHANGE( rmesa
, ctx
);
1671 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1672 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1673 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1675 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1680 RADEON_STATECHANGE( rmesa
, tcl
);
1682 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1684 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1688 case GL_POLYGON_OFFSET_POINT
:
1689 RADEON_STATECHANGE( rmesa
, set
);
1691 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1693 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1697 case GL_POLYGON_OFFSET_LINE
:
1698 RADEON_STATECHANGE( rmesa
, set
);
1700 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1702 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1706 case GL_POLYGON_OFFSET_FILL
:
1707 RADEON_STATECHANGE( rmesa
, set
);
1709 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1711 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1715 case GL_POLYGON_SMOOTH
:
1716 RADEON_STATECHANGE( rmesa
, ctx
);
1718 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1720 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1724 case GL_POLYGON_STIPPLE
:
1725 RADEON_STATECHANGE(rmesa
, ctx
);
1727 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1729 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1733 case GL_RESCALE_NORMAL_EXT
: {
1734 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1735 RADEON_STATECHANGE( rmesa
, tcl
);
1737 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1739 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1744 case GL_SCISSOR_TEST
:
1745 radeon_firevertices(&rmesa
->radeon
);
1746 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1747 radeonUpdateScissor( ctx
);
1750 case GL_STENCIL_TEST
:
1752 GLboolean hw_stencil
= GL_FALSE
;
1753 if (ctx
->DrawBuffer
) {
1754 struct radeon_renderbuffer
*rrbStencil
1755 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
1756 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
1760 RADEON_STATECHANGE( rmesa
, ctx
);
1762 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1764 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1767 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1772 case GL_TEXTURE_GEN_Q
:
1773 case GL_TEXTURE_GEN_R
:
1774 case GL_TEXTURE_GEN_S
:
1775 case GL_TEXTURE_GEN_T
:
1776 /* Picked up in radeonUpdateTextureState.
1778 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1781 case GL_COLOR_SUM_EXT
:
1782 radeonUpdateSpecular ( ctx
);
1791 static void radeonLightingSpaceChange( struct gl_context
*ctx
)
1793 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1795 RADEON_STATECHANGE( rmesa
, tcl
);
1797 if (RADEON_DEBUG
& RADEON_STATE
)
1798 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1799 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1801 if (ctx
->_NeedEyeCoords
)
1802 tmp
= ctx
->Transform
.RescaleNormals
;
1804 tmp
= !ctx
->Transform
.RescaleNormals
;
1807 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1809 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1812 if (RADEON_DEBUG
& RADEON_STATE
)
1813 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1814 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1817 /* =============================================================
1818 * Deferred state management - matrices, textures, other?
1822 void radeonUploadTexMatrix( r100ContextPtr rmesa
,
1823 int unit
, GLboolean swapcols
)
1825 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1826 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1827 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1828 texgen generates all 4 coords, at least tests with projtex indicated that.
1829 So: if we need the q coord in the end (solely determined by the texture
1830 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1831 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1832 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1833 will get submitted in the "wrong", i.e. 3rd, slot.
1834 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1835 size and using the texture matrix to swap the r and q coords around (ut2k3
1836 does exactly that), so we don't need the 3rd / 4th column swap - still need
1837 the 3rd / 4th row swap of course. This will potentially break for apps which
1838 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1839 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1840 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1841 incredibly hard to detect so we can't just fallback in such a case. Assume
1842 it never happens... - rs
1845 int idx
= TEXMAT_0
+ unit
;
1846 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
1848 struct gl_texture_unit tUnit
= rmesa
->radeon
.glCtx
.Texture
.Unit
[unit
];
1849 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
1851 rmesa
->TexMatColSwap
&= ~(1 << unit
);
1852 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
1854 rmesa
->TexMatColSwap
|= 1 << unit
;
1855 /* attention some elems are swapped 2 times! */
1868 /* those last 4 are probably never used */
1875 for (i
= 0; i
< 2; i
++) {
1879 *dest
++ = src
[i
+12];
1881 for (i
= 3; i
>= 2; i
--) {
1885 *dest
++ = src
[i
+12];
1890 for (i
= 0 ; i
< 4 ; i
++) {
1894 *dest
++ = src
[i
+12];
1898 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1902 static void upload_matrix( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1904 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1908 for (i
= 0 ; i
< 4 ; i
++) {
1912 *dest
++ = src
[i
+12];
1915 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1918 static void upload_matrix_t( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1920 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1921 memcpy(dest
, src
, 16*sizeof(float));
1922 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1926 static void update_texturematrix( struct gl_context
*ctx
)
1928 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
1929 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
1930 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
1932 GLuint texMatEnabled
= 0;
1933 rmesa
->NeedTexMatrix
= 0;
1934 rmesa
->TexMatColSwap
= 0;
1936 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
1937 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
1938 GLboolean needMatrix
= GL_FALSE
;
1939 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
1940 needMatrix
= GL_TRUE
;
1941 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
1942 RADEON_TEXMAT_0_ENABLE
) << unit
;
1944 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1945 /* Need to preconcatenate any active texgen
1946 * obj/eyeplane matrices:
1948 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
1949 ctx
->TextureMatrixStack
[unit
].Top
,
1950 &rmesa
->TexGenMatrix
[unit
] );
1953 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
1954 ctx
->TextureMatrixStack
[unit
].Top
);
1957 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1958 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
1959 needMatrix
= GL_TRUE
;
1962 rmesa
->NeedTexMatrix
|= 1 << unit
;
1963 radeonUploadTexMatrix( rmesa
, unit
,
1964 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
1969 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
1971 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1972 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
1973 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
1974 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
1976 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
1977 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
1978 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
1979 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
1980 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
1981 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
1983 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
1984 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
1986 RADEON_STATECHANGE(rmesa
, tcl
);
1987 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
1988 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
1992 static GLboolean
r100ValidateBuffers(struct gl_context
*ctx
)
1994 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1995 struct radeon_renderbuffer
*rrb
;
1998 radeon_cs_space_reset_bos(rmesa
->radeon
.cmdbuf
.cs
);
2000 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
2002 if (rrb
&& rrb
->bo
) {
2003 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
2004 0, RADEON_GEM_DOMAIN_VRAM
);
2008 rrb
= radeon_get_depthbuffer(&rmesa
->radeon
);
2010 if (rrb
&& rrb
->bo
) {
2011 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
2012 0, RADEON_GEM_DOMAIN_VRAM
);
2015 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; ++i
) {
2018 if (!ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2021 t
= rmesa
->state
.texture
.unit
[i
].texobj
;
2025 if (t
->image_override
&& t
->bo
)
2026 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->bo
,
2027 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
2029 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->mt
->bo
,
2030 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
2033 ret
= radeon_cs_space_check_with_bo(rmesa
->radeon
.cmdbuf
.cs
, first_elem(&rmesa
->radeon
.dma
.reserved
)->bo
, RADEON_GEM_DOMAIN_GTT
, 0);
2039 GLboolean
radeonValidateState( struct gl_context
*ctx
)
2041 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2042 GLuint new_state
= rmesa
->radeon
.NewGLState
;
2044 if (new_state
& _NEW_BUFFERS
) {
2045 _mesa_update_framebuffer(ctx
);
2046 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2047 _mesa_update_draw_buffer_bounds(ctx
);
2048 RADEON_STATECHANGE(rmesa
, ctx
);
2051 if (new_state
& _NEW_TEXTURE
) {
2052 radeonUpdateTextureState( ctx
);
2053 new_state
|= rmesa
->radeon
.NewGLState
; /* may add TEXTURE_MATRIX */
2056 /* we need to do a space check here */
2057 if (!r100ValidateBuffers(ctx
))
2060 /* Need an event driven matrix update?
2062 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2063 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2065 /* Need these for lighting (shouldn't upload otherwise)
2067 if (new_state
& (_NEW_MODELVIEW
)) {
2068 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2069 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2072 /* Does this need to be triggered on eg. modelview for
2073 * texgen-derived objplane/eyeplane matrices?
2075 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2076 update_texturematrix( ctx
);
2079 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2080 update_light( ctx
);
2083 /* emit all active clip planes if projection matrix changes.
2085 if (new_state
& (_NEW_PROJECTION
)) {
2086 if (ctx
->Transform
.ClipPlanesEnabled
)
2087 radeonUpdateClipPlanes( ctx
);
2091 rmesa
->radeon
.NewGLState
= 0;
2097 static void radeonInvalidateState( struct gl_context
*ctx
, GLuint new_state
)
2099 _swrast_InvalidateState( ctx
, new_state
);
2100 _swsetup_InvalidateState( ctx
, new_state
);
2101 _vbo_InvalidateState( ctx
, new_state
);
2102 _tnl_InvalidateState( ctx
, new_state
);
2103 _ae_invalidate_state( ctx
, new_state
);
2104 R100_CONTEXT(ctx
)->radeon
.NewGLState
|= new_state
;
2108 /* A hack. Need a faster way to find this out.
2110 static GLboolean
check_material( struct gl_context
*ctx
)
2112 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2115 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2116 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2118 if (tnl
->vb
.AttribPtr
[i
] &&
2119 tnl
->vb
.AttribPtr
[i
]->stride
)
2126 static void radeonWrapRunPipeline( struct gl_context
*ctx
)
2128 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2129 GLboolean has_material
;
2132 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->radeon
.NewGLState
);
2136 if (rmesa
->radeon
.NewGLState
)
2137 if (!radeonValidateState( ctx
))
2138 FALLBACK(rmesa
, RADEON_FALLBACK_TEXTURE
, GL_TRUE
);
2140 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2143 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2146 /* Run the pipeline.
2148 _tnl_run_pipeline( ctx
);
2151 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2155 static void radeonPolygonStipple( struct gl_context
*ctx
, const GLubyte
*mask
)
2157 r100ContextPtr r100
= R100_CONTEXT(ctx
);
2160 radeon_firevertices(&r100
->radeon
);
2162 RADEON_STATECHANGE(r100
, stp
);
2164 /* Must flip pattern upside down.
2166 for ( i
= 31 ; i
>= 0; i
--) {
2167 r100
->hw
.stp
.cmd
[3 + i
] = ((GLuint
*) mask
)[i
];
2172 /* Initialize the driver's state functions.
2173 * Many of the ctx->Driver functions might have been initialized to
2174 * software defaults in the earlier _mesa_init_driver_functions() call.
2176 void radeonInitStateFuncs( struct gl_context
*ctx
)
2178 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2179 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2181 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2182 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2183 ctx
->Driver
.CopyPixels
= _mesa_meta_CopyPixels
;
2184 ctx
->Driver
.DrawPixels
= _mesa_meta_DrawPixels
;
2185 ctx
->Driver
.ReadPixels
= radeonReadPixels
;
2187 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2188 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2189 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2190 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2191 ctx
->Driver
.ColorMask
= radeonColorMask
;
2192 ctx
->Driver
.CullFace
= radeonCullFace
;
2193 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2194 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2195 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2196 ctx
->Driver
.Enable
= radeonEnable
;
2197 ctx
->Driver
.Fogfv
= radeonFogfv
;
2198 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2199 ctx
->Driver
.Hint
= NULL
;
2200 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2201 ctx
->Driver
.Lightfv
= radeonLightfv
;
2202 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2203 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2204 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2205 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2206 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2207 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2208 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2209 ctx
->Driver
.Scissor
= radeonScissor
;
2210 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2211 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2212 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2213 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2214 ctx
->Driver
.Viewport
= radeonViewport
;
2216 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2217 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;