1 /**************************************************************************
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/state.h"
41 #include "main/context.h"
42 #include "main/framebuffer.h"
46 #include "tnl/t_pipeline.h"
47 #include "swrast_setup/swrast_setup.h"
49 #include "radeon_context.h"
50 #include "radeon_ioctl.h"
51 #include "radeon_state.h"
52 #include "radeon_tcl.h"
53 #include "radeon_tex.h"
54 #include "radeon_swtcl.h"
55 #include "drirenderbuffer.h"
57 static void radeonUpdateSpecular( GLcontext
*ctx
);
59 /* =============================================================
63 static void radeonAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
65 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
66 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
69 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
71 RADEON_STATECHANGE( rmesa
, ctx
);
73 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
74 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
78 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
81 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
84 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
87 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
90 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
93 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
96 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
99 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
103 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
106 static void radeonBlendEquationSeparate( GLcontext
*ctx
,
107 GLenum modeRGB
, GLenum modeA
)
109 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
110 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
111 GLboolean fallback
= GL_FALSE
;
113 assert( modeRGB
== modeA
);
118 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
121 case GL_FUNC_SUBTRACT
:
122 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
126 if (ctx
->Color
.BlendEnabled
)
129 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
133 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
135 RADEON_STATECHANGE( rmesa
, ctx
);
136 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
137 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
138 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
139 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
141 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
146 static void radeonBlendFuncSeparate( GLcontext
*ctx
,
147 GLenum sfactorRGB
, GLenum dfactorRGB
,
148 GLenum sfactorA
, GLenum dfactorA
)
150 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
151 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
152 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
153 GLboolean fallback
= GL_FALSE
;
155 switch ( ctx
->Color
.BlendSrcRGB
) {
157 b
|= RADEON_SRC_BLEND_GL_ZERO
;
160 b
|= RADEON_SRC_BLEND_GL_ONE
;
163 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
165 case GL_ONE_MINUS_DST_COLOR
:
166 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
169 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
171 case GL_ONE_MINUS_SRC_COLOR
:
172 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
175 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
177 case GL_ONE_MINUS_SRC_ALPHA
:
178 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
181 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
183 case GL_ONE_MINUS_DST_ALPHA
:
184 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
186 case GL_SRC_ALPHA_SATURATE
:
187 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
189 case GL_CONSTANT_COLOR
:
190 case GL_ONE_MINUS_CONSTANT_COLOR
:
191 case GL_CONSTANT_ALPHA
:
192 case GL_ONE_MINUS_CONSTANT_ALPHA
:
193 if (ctx
->Color
.BlendEnabled
)
196 b
|= RADEON_SRC_BLEND_GL_ONE
;
202 switch ( ctx
->Color
.BlendDstRGB
) {
204 b
|= RADEON_DST_BLEND_GL_ZERO
;
207 b
|= RADEON_DST_BLEND_GL_ONE
;
210 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
212 case GL_ONE_MINUS_SRC_COLOR
:
213 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
216 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
218 case GL_ONE_MINUS_SRC_ALPHA
:
219 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
222 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
224 case GL_ONE_MINUS_DST_COLOR
:
225 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
228 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
230 case GL_ONE_MINUS_DST_ALPHA
:
231 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
233 case GL_CONSTANT_COLOR
:
234 case GL_ONE_MINUS_CONSTANT_COLOR
:
235 case GL_CONSTANT_ALPHA
:
236 case GL_ONE_MINUS_CONSTANT_ALPHA
:
237 if (ctx
->Color
.BlendEnabled
)
240 b
|= RADEON_DST_BLEND_GL_ZERO
;
246 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
248 RADEON_STATECHANGE( rmesa
, ctx
);
249 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
254 /* =============================================================
258 static void radeonDepthFunc( GLcontext
*ctx
, GLenum func
)
260 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
262 RADEON_STATECHANGE( rmesa
, ctx
);
263 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
265 switch ( ctx
->Depth
.Func
) {
267 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
294 static void radeonDepthMask( GLcontext
*ctx
, GLboolean flag
)
296 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
297 RADEON_STATECHANGE( rmesa
, ctx
);
299 if ( ctx
->Depth
.Mask
) {
300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
306 static void radeonClearDepth( GLcontext
*ctx
, GLclampd d
)
308 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
309 GLuint format
= (rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &
310 RADEON_DEPTH_FORMAT_MASK
);
313 case RADEON_DEPTH_FORMAT_16BIT_INT_Z
:
314 rmesa
->radeon
.state
.depth
.clear
= d
* 0x0000ffff;
316 case RADEON_DEPTH_FORMAT_24BIT_INT_Z
:
317 rmesa
->radeon
.state
.depth
.clear
= d
* 0x00ffffff;
323 /* =============================================================
328 static void radeonFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
330 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
331 union { int i
; float f
; } c
, d
;
336 if (!ctx
->Fog
.Enabled
)
338 RADEON_STATECHANGE(rmesa
, tcl
);
339 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
340 switch (ctx
->Fog
.Mode
) {
342 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
345 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
348 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
357 if (!ctx
->Fog
.Enabled
)
359 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
360 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
361 switch (ctx
->Fog
.Mode
) {
364 /* While this is the opposite sign from the DDK, it makes the fog test
365 * pass, and matches r200.
367 d
.f
= -ctx
->Fog
.Density
;
371 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
374 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
378 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
379 /* While this is the opposite sign from the DDK, it makes the fog
380 * test pass, and matches r200.
382 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
388 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
389 RADEON_STATECHANGE( rmesa
, fog
);
390 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
391 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
395 RADEON_STATECHANGE( rmesa
, ctx
);
396 UNCLAMPED_FLOAT_TO_RGB_CHAN( col
, ctx
->Fog
.Color
);
397 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
398 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
399 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
401 case GL_FOG_COORD_SRC
:
402 radeonUpdateSpecular( ctx
);
409 /* =============================================================
413 static void radeonCullFace( GLcontext
*ctx
, GLenum unused
)
415 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
416 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
417 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
419 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
420 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
422 if ( ctx
->Polygon
.CullFlag
) {
423 switch ( ctx
->Polygon
.CullFaceMode
) {
425 s
&= ~RADEON_FFACE_SOLID
;
426 t
|= RADEON_CULL_FRONT
;
429 s
&= ~RADEON_BFACE_SOLID
;
430 t
|= RADEON_CULL_BACK
;
432 case GL_FRONT_AND_BACK
:
433 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
434 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
439 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
440 RADEON_STATECHANGE(rmesa
, set
);
441 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
444 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
445 RADEON_STATECHANGE(rmesa
, tcl
);
446 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
450 static void radeonFrontFace( GLcontext
*ctx
, GLenum mode
)
452 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
454 RADEON_STATECHANGE( rmesa
, set
);
455 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
457 RADEON_STATECHANGE( rmesa
, tcl
);
458 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
462 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
465 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
466 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
472 /* =============================================================
475 static void radeonLineWidth( GLcontext
*ctx
, GLfloat widthf
)
477 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
479 RADEON_STATECHANGE( rmesa
, lin
);
480 RADEON_STATECHANGE( rmesa
, set
);
482 /* Line width is stored in U6.4 format.
484 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
485 if ( widthf
> 1.0 ) {
486 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
488 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
492 static void radeonLineStipple( GLcontext
*ctx
, GLint factor
, GLushort pattern
)
494 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
496 RADEON_STATECHANGE( rmesa
, lin
);
497 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
498 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
502 /* =============================================================
505 static void radeonColorMask( GLcontext
*ctx
,
506 GLboolean r
, GLboolean g
,
507 GLboolean b
, GLboolean a
)
509 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
510 GLuint mask
= radeonPackColor( rmesa
->radeon
.radeonScreen
->cpp
,
511 ctx
->Color
.ColorMask
[RCOMP
],
512 ctx
->Color
.ColorMask
[GCOMP
],
513 ctx
->Color
.ColorMask
[BCOMP
],
514 ctx
->Color
.ColorMask
[ACOMP
] );
516 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
517 RADEON_STATECHANGE( rmesa
, msk
);
518 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
523 /* =============================================================
527 static void radeonPolygonOffset( GLcontext
*ctx
,
528 GLfloat factor
, GLfloat units
)
530 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
531 float_ui32_type constant
= { units
* rmesa
->radeon
.state
.depth
.scale
};
532 float_ui32_type factoru
= { factor
};
534 RADEON_STATECHANGE( rmesa
, zbs
);
535 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
536 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
539 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
541 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
543 drm_radeon_stipple_t stipple
;
545 /* Must flip pattern upside down.
547 for ( i
= 0 ; i
< 32 ; i
++ ) {
548 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
551 /* TODO: push this into cmd mechanism
553 radeon_firevertices(&rmesa
->radeon
);
554 LOCK_HARDWARE( &rmesa
->radeon
);
556 /* FIXME: Use window x,y offsets into stipple RAM.
558 stipple
.mask
= rmesa
->state
.stipple
.mask
;
559 drmCommandWrite( rmesa
->radeon
.dri
.fd
, DRM_RADEON_STIPPLE
,
560 &stipple
, sizeof(drm_radeon_stipple_t
) );
561 UNLOCK_HARDWARE( &rmesa
->radeon
);
564 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
566 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
567 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
569 /* Can't generally do unfilled via tcl, but some good special
572 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
573 if (rmesa
->radeon
.TclFallback
) {
574 radeonChooseRenderState( ctx
);
575 radeonChooseVertexState( ctx
);
580 /* =============================================================
581 * Rendering attributes
583 * We really don't want to recalculate all this every time we bind a
584 * texture. These things shouldn't change all that often, so it makes
585 * sense to break them out of the core texture state update routines.
588 /* Examine lighting and texture state to determine if separate specular
591 static void radeonUpdateSpecular( GLcontext
*ctx
)
593 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
594 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
597 RADEON_STATECHANGE( rmesa
, tcl
);
599 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
600 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
601 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
602 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
603 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
605 p
&= ~RADEON_SPECULAR_ENABLE
;
607 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
610 if (ctx
->Light
.Enabled
&&
611 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
612 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
613 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
614 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
615 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
616 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
617 p
|= RADEON_SPECULAR_ENABLE
;
618 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
619 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
621 else if (ctx
->Light
.Enabled
) {
622 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
623 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
624 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
625 } else if (ctx
->Fog
.ColorSumEnabled
) {
626 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
627 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
628 p
|= RADEON_SPECULAR_ENABLE
;
630 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
633 if (ctx
->Fog
.Enabled
) {
634 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
635 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
636 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
637 /* Bizzare: have to leave lighting enabled to get fog. */
638 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
641 /* cannot do tcl fog factor calculation with fog coord source
642 * (send precomputed factors). Cannot use precomputed fog
643 * factors together with tcl spec light (need tcl fallback) */
644 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
645 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
649 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
651 if (NEED_SECONDARY_COLOR(ctx
)) {
652 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
654 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
657 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
658 RADEON_STATECHANGE( rmesa
, ctx
);
659 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
662 /* Update vertex/render formats
664 if (rmesa
->radeon
.TclFallback
) {
665 radeonChooseRenderState( ctx
);
666 radeonChooseVertexState( ctx
);
671 /* =============================================================
676 /* Update on colormaterial, material emmissive/ambient,
677 * lightmodel.globalambient
679 static void update_global_ambient( GLcontext
*ctx
)
681 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
682 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
684 /* Need to do more if both emmissive & ambient are PREMULT:
685 * Hope this is not needed for MULT
687 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
688 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
689 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
691 COPY_3V( &fcmd
[GLT_RED
],
692 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
693 ACC_SCALE_3V( &fcmd
[GLT_RED
],
694 ctx
->Light
.Model
.Ambient
,
695 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
699 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
702 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
705 /* Update on change to
709 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
711 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
713 /* fprintf(stderr, "%s\n", __FUNCTION__); */
716 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
717 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
719 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
720 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
721 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
723 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
727 /* Also fallback for asym colormaterial mode in twoside lighting...
729 static void check_twoside_fallback( GLcontext
*ctx
)
731 GLboolean fallback
= GL_FALSE
;
734 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
735 if (ctx
->Light
.ColorMaterialEnabled
&&
736 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
737 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
740 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
741 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
742 ctx
->Light
.Material
.Attrib
[i
+1],
743 sizeof(GLfloat
)*4) != 0) {
750 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
754 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
756 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
757 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
759 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
760 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
761 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
762 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
764 if (ctx
->Light
.ColorMaterialEnabled
) {
765 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
767 if (mask
& MAT_BIT_FRONT_EMISSION
) {
768 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
769 RADEON_EMISSIVE_SOURCE_SHIFT
);
772 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
773 RADEON_EMISSIVE_SOURCE_SHIFT
);
776 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
777 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
778 RADEON_AMBIENT_SOURCE_SHIFT
);
781 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
782 RADEON_AMBIENT_SOURCE_SHIFT
);
785 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
786 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
787 RADEON_DIFFUSE_SOURCE_SHIFT
);
790 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
791 RADEON_DIFFUSE_SOURCE_SHIFT
);
794 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
795 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
796 RADEON_SPECULAR_SOURCE_SHIFT
);
799 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
800 RADEON_SPECULAR_SOURCE_SHIFT
);
806 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
807 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
808 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
809 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
812 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
813 RADEON_STATECHANGE( rmesa
, tcl
);
814 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
818 void radeonUpdateMaterial( GLcontext
*ctx
)
820 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
821 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
822 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
825 if (ctx
->Light
.ColorMaterialEnabled
)
826 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
828 if (RADEON_DEBUG
& DEBUG_STATE
)
829 fprintf(stderr
, "%s\n", __FUNCTION__
);
832 if (mask
& MAT_BIT_FRONT_EMISSION
) {
833 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
834 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
835 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
836 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
838 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
839 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
840 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
841 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
842 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
844 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
845 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
846 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
847 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
848 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
850 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
851 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
852 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
853 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
854 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
856 if (mask
& MAT_BIT_FRONT_SHININESS
) {
857 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
860 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
862 check_twoside_fallback( ctx
);
863 /* update_global_ambient( ctx );*/
868 * _MESA_NEW_NEED_EYE_COORDS
870 * Uses derived state from mesa:
879 * which are calculated in light.c and are correct for the current
880 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
881 * and _MESA_NEW_NEED_EYE_COORDS.
883 static void update_light( GLcontext
*ctx
)
885 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
887 /* Have to check these, or have an automatic shortcircuit mechanism
888 * to remove noop statechanges. (Or just do a better job on the
892 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
894 if (ctx
->_NeedEyeCoords
)
895 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
897 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
900 /* Leave this test disabled: (unexplained q3 lockup) (even with
903 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
905 RADEON_STATECHANGE( rmesa
, tcl
);
906 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
911 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
912 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
913 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
914 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
915 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
916 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
921 if (ctx
->Light
.Enabled
) {
923 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
924 if (ctx
->Light
.Light
[p
].Enabled
) {
925 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
926 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
928 if (l
->EyePosition
[3] == 0.0) {
929 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
930 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
931 fcmd
[LIT_POSITION_W
] = 0;
932 fcmd
[LIT_DIRECTION_W
] = 0;
934 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
935 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
936 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
937 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
938 fcmd
[LIT_DIRECTION_W
] = 0;
941 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
947 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
948 GLenum pname
, const GLfloat
*params
)
950 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
951 GLint p
= light
- GL_LIGHT0
;
952 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
953 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
960 update_light_colors( ctx
, p
);
963 case GL_SPOT_DIRECTION
:
964 /* picked up in update_light */
968 /* positions picked up in update_light, but can do flag here */
970 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
972 /* FIXME: Set RANGE_ATTEN only when needed */
974 flag
= RADEON_LIGHT_1_IS_LOCAL
;
976 flag
= RADEON_LIGHT_0_IS_LOCAL
;
978 RADEON_STATECHANGE(rmesa
, tcl
);
979 if (l
->EyePosition
[3] != 0.0F
)
980 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
982 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
986 case GL_SPOT_EXPONENT
:
987 RADEON_STATECHANGE(rmesa
, lit
[p
]);
988 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
991 case GL_SPOT_CUTOFF
: {
992 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
993 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
995 RADEON_STATECHANGE(rmesa
, lit
[p
]);
996 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
998 RADEON_STATECHANGE(rmesa
, tcl
);
999 if (l
->SpotCutoff
!= 180.0F
)
1000 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1002 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1007 case GL_CONSTANT_ATTENUATION
:
1008 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1009 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1010 if ( params
[0] == 0.0 )
1011 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1013 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1015 case GL_LINEAR_ATTENUATION
:
1016 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1017 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1019 case GL_QUADRATIC_ATTENUATION
:
1020 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1021 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1027 /* Set RANGE_ATTEN only when needed */
1030 case GL_CONSTANT_ATTENUATION
:
1031 case GL_LINEAR_ATTENUATION
:
1032 case GL_QUADRATIC_ATTENUATION
:
1034 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1035 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1036 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1037 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1038 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1039 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1041 if ( l
->EyePosition
[3] == 0.0F
||
1042 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1043 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1044 /* Disable attenuation */
1045 icmd
[idx
] &= ~atten_flag
;
1047 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1048 /* Enable only constant portion of attenuation calculation */
1049 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1051 /* Enable full attenuation calculation */
1052 icmd
[idx
] &= ~atten_const_flag
;
1053 icmd
[idx
] |= atten_flag
;
1057 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1068 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1069 const GLfloat
*param
)
1071 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1074 case GL_LIGHT_MODEL_AMBIENT
:
1075 update_global_ambient( ctx
);
1078 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1079 RADEON_STATECHANGE( rmesa
, tcl
);
1080 if (ctx
->Light
.Model
.LocalViewer
)
1081 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1083 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1086 case GL_LIGHT_MODEL_TWO_SIDE
:
1087 RADEON_STATECHANGE( rmesa
, tcl
);
1088 if (ctx
->Light
.Model
.TwoSide
)
1089 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1091 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1093 check_twoside_fallback( ctx
);
1095 if (rmesa
->radeon
.TclFallback
) {
1096 radeonChooseRenderState( ctx
);
1097 radeonChooseVertexState( ctx
);
1101 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1102 radeonUpdateSpecular(ctx
);
1110 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1112 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1113 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1115 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1116 RADEON_ALPHA_SHADE_MASK
|
1117 RADEON_SPECULAR_SHADE_MASK
|
1118 RADEON_FOG_SHADE_MASK
);
1122 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1123 RADEON_ALPHA_SHADE_FLAT
|
1124 RADEON_SPECULAR_SHADE_FLAT
|
1125 RADEON_FOG_SHADE_FLAT
);
1128 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1129 RADEON_ALPHA_SHADE_GOURAUD
|
1130 RADEON_SPECULAR_SHADE_GOURAUD
|
1131 RADEON_FOG_SHADE_GOURAUD
);
1137 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1138 RADEON_STATECHANGE( rmesa
, set
);
1139 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1144 /* =============================================================
1148 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1150 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1151 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1152 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1154 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1155 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1156 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1157 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1158 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1161 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1163 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1166 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1167 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1168 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1170 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1171 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1172 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1173 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1174 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1180 /* =============================================================
1185 radeonStencilFuncSeparate( GLcontext
*ctx
, GLenum face
, GLenum func
,
1186 GLint ref
, GLuint mask
)
1188 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1189 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << RADEON_STENCIL_REF_SHIFT
) |
1190 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1192 RADEON_STATECHANGE( rmesa
, ctx
);
1193 RADEON_STATECHANGE( rmesa
, msk
);
1195 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1196 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1197 RADEON_STENCIL_VALUE_MASK
);
1199 switch ( ctx
->Stencil
.Function
[0] ) {
1201 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1204 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1207 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1210 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1213 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1216 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1219 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1222 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1226 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1230 radeonStencilMaskSeparate( GLcontext
*ctx
, GLenum face
, GLuint mask
)
1232 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1234 RADEON_STATECHANGE( rmesa
, msk
);
1235 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1236 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1237 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1240 static void radeonStencilOpSeparate( GLcontext
*ctx
, GLenum face
, GLenum fail
,
1241 GLenum zfail
, GLenum zpass
)
1243 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1245 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1246 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1247 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1249 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1250 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1251 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1252 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1253 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1254 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1256 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1257 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1258 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1259 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1260 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1261 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1262 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1265 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1266 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1267 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1268 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1269 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1270 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1273 RADEON_STATECHANGE( rmesa
, ctx
);
1274 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1275 RADEON_STENCIL_ZFAIL_MASK
|
1276 RADEON_STENCIL_ZPASS_MASK
);
1278 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1280 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1283 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1286 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1289 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1292 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1295 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1298 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1301 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1305 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1307 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1310 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1313 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1316 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1319 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1322 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1325 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1328 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1332 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1334 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1337 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1340 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1343 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1346 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1349 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1352 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1355 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1360 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1362 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1364 rmesa
->radeon
.state
.stencil
.clear
=
1365 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
1366 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1367 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
));
1371 /* =============================================================
1372 * Window position and viewport transformation
1376 * To correctly position primitives:
1378 #define SUBPIXEL_X 0.125
1379 #define SUBPIXEL_Y 0.125
1383 * Called when window size or position changes or viewport or depth range
1384 * state is changed. We update the hardware viewport state here.
1386 void radeonUpdateWindow( GLcontext
*ctx
)
1388 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1389 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1390 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
1391 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
1392 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1394 float_ui32_type sx
= { v
[MAT_SX
] };
1395 float_ui32_type tx
= { v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
};
1396 float_ui32_type sy
= { - v
[MAT_SY
] };
1397 float_ui32_type ty
= { (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
};
1398 float_ui32_type sz
= { v
[MAT_SZ
] * rmesa
->radeon
.state
.depth
.scale
};
1399 float_ui32_type tz
= { v
[MAT_TZ
] * rmesa
->radeon
.state
.depth
.scale
};
1401 radeon_firevertices(&rmesa
->radeon
);
1402 RADEON_STATECHANGE( rmesa
, vpt
);
1404 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1405 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1406 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1407 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1408 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1409 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1413 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1414 GLsizei width
, GLsizei height
)
1416 /* Don't pipeline viewport changes, conflict with window offset
1417 * setting below. Could apply deltas to rescue pipelined viewport
1418 * values, or keep the originals hanging around.
1420 radeonUpdateWindow( ctx
);
1423 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1426 radeonUpdateWindow( ctx
);
1429 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1431 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1432 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1433 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1434 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1435 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1440 tx
.f
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1441 ty
.f
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1443 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != tx
.ui32
||
1444 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != ty
.ui32
)
1446 /* Note: this should also modify whatever data the context reset
1449 RADEON_STATECHANGE( rmesa
, vpt
);
1450 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1451 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1453 /* update polygon stipple x/y screen offset */
1456 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1458 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1459 RADEON_STIPPLE_Y_OFFSET_MASK
);
1461 /* add magic offsets, then invert */
1462 stx
= 31 - ((rmesa
->radeon
.dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1463 sty
= 31 - ((rmesa
->radeon
.dri
.drawable
->y
+ rmesa
->radeon
.dri
.drawable
->h
- 1)
1464 & RADEON_STIPPLE_COORD_MASK
);
1466 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1467 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1469 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1470 RADEON_STATECHANGE( rmesa
, msc
);
1471 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1476 radeonUpdateScissor( ctx
);
1481 /* =============================================================
1485 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1487 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1489 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1490 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1491 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1492 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1493 rmesa
->radeon
.state
.color
.clear
= radeonPackColor( rmesa
->radeon
.radeonScreen
->cpp
,
1494 c
[0], c
[1], c
[2], c
[3] );
1498 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1500 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1501 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1505 static GLuint radeon_rop_tab
[] = {
1508 RADEON_ROP_AND_REVERSE
,
1510 RADEON_ROP_AND_INVERTED
,
1517 RADEON_ROP_OR_REVERSE
,
1518 RADEON_ROP_COPY_INVERTED
,
1519 RADEON_ROP_OR_INVERTED
,
1524 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1526 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1527 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1531 RADEON_STATECHANGE( rmesa
, msk
);
1532 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1537 * Called via glDrawBuffer.
1539 static void radeonDrawBuffer( GLcontext
*ctx
, GLenum mode
)
1541 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1543 if (RADEON_DEBUG
& DEBUG_DRI
)
1544 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
1545 _mesa_lookup_enum_by_nr( mode
));
1547 radeon_firevertices(&rmesa
->radeon
); /* don't pipeline cliprect changes */
1549 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
!= 1) {
1550 /* 0 (GL_NONE) buffers or multiple color drawing buffers */
1551 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1555 switch ( ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] ) {
1556 case BUFFER_FRONT_LEFT
:
1557 case BUFFER_BACK_LEFT
:
1558 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1561 FALLBACK( rmesa
, RADEON_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1565 radeonSetCliprects( &rmesa
->radeon
);
1566 if (!rmesa
->radeon
.radeonScreen
->driScreen
->dri2
.enabled
)
1567 radeonUpdatePageFlipping(&rmesa
->radeon
);
1568 /* We'll set the drawing engine's offset/pitch parameters later
1569 * when we update other state.
1573 static void radeonReadBuffer( GLcontext
*ctx
, GLenum mode
)
1575 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1579 /* =============================================================
1580 * State enable/disable
1583 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1585 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1588 if ( RADEON_DEBUG
& DEBUG_STATE
)
1589 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1590 _mesa_lookup_enum_by_nr( cap
),
1591 state
? "GL_TRUE" : "GL_FALSE" );
1594 /* Fast track this one...
1602 RADEON_STATECHANGE( rmesa
, ctx
);
1604 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1606 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1611 RADEON_STATECHANGE( rmesa
, ctx
);
1613 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1615 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1617 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1618 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1619 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1621 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1624 /* Catch a possible fallback:
1627 ctx
->Driver
.BlendEquationSeparate( ctx
,
1628 ctx
->Color
.BlendEquationRGB
,
1629 ctx
->Color
.BlendEquationA
);
1630 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1631 ctx
->Color
.BlendDstRGB
,
1632 ctx
->Color
.BlendSrcA
,
1633 ctx
->Color
.BlendDstA
);
1636 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1637 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1641 case GL_CLIP_PLANE0
:
1642 case GL_CLIP_PLANE1
:
1643 case GL_CLIP_PLANE2
:
1644 case GL_CLIP_PLANE3
:
1645 case GL_CLIP_PLANE4
:
1646 case GL_CLIP_PLANE5
:
1647 p
= cap
-GL_CLIP_PLANE0
;
1648 RADEON_STATECHANGE( rmesa
, tcl
);
1650 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1651 radeonClipPlane( ctx
, cap
, NULL
);
1654 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1658 case GL_COLOR_MATERIAL
:
1659 radeonColorMaterial( ctx
, 0, 0 );
1660 radeonUpdateMaterial( ctx
);
1664 radeonCullFace( ctx
, 0 );
1668 RADEON_STATECHANGE(rmesa
, ctx
);
1670 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1672 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1677 RADEON_STATECHANGE(rmesa
, ctx
);
1679 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1680 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->radeon
.state
.color
.roundEnable
;
1682 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1683 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->radeon
.state
.color
.roundEnable
;
1688 RADEON_STATECHANGE(rmesa
, ctx
);
1690 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1691 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1693 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1694 RADEON_STATECHANGE(rmesa
, tcl
);
1695 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1697 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1698 _mesa_allow_light_in_model( ctx
, !state
);
1709 RADEON_STATECHANGE(rmesa
, tcl
);
1710 p
= cap
- GL_LIGHT0
;
1712 flag
= (RADEON_LIGHT_1_ENABLE
|
1713 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1714 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1716 flag
= (RADEON_LIGHT_0_ENABLE
|
1717 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1718 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1721 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1723 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1727 update_light_colors( ctx
, p
);
1731 RADEON_STATECHANGE(rmesa
, tcl
);
1732 radeonUpdateSpecular(ctx
);
1733 check_twoside_fallback( ctx
);
1736 case GL_LINE_SMOOTH
:
1737 RADEON_STATECHANGE( rmesa
, ctx
);
1739 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1741 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1745 case GL_LINE_STIPPLE
:
1746 RADEON_STATECHANGE( rmesa
, ctx
);
1748 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1750 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1754 case GL_COLOR_LOGIC_OP
:
1755 RADEON_STATECHANGE( rmesa
, ctx
);
1756 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1757 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1758 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1760 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1765 RADEON_STATECHANGE( rmesa
, tcl
);
1767 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1769 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1773 case GL_POLYGON_OFFSET_POINT
:
1774 RADEON_STATECHANGE( rmesa
, set
);
1776 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1778 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1782 case GL_POLYGON_OFFSET_LINE
:
1783 RADEON_STATECHANGE( rmesa
, set
);
1785 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1787 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1791 case GL_POLYGON_OFFSET_FILL
:
1792 RADEON_STATECHANGE( rmesa
, set
);
1794 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1796 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1800 case GL_POLYGON_SMOOTH
:
1801 RADEON_STATECHANGE( rmesa
, ctx
);
1803 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1805 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1809 case GL_POLYGON_STIPPLE
:
1810 RADEON_STATECHANGE(rmesa
, ctx
);
1812 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1814 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1818 case GL_RESCALE_NORMAL_EXT
: {
1819 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1820 RADEON_STATECHANGE( rmesa
, tcl
);
1822 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1824 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1829 case GL_SCISSOR_TEST
:
1830 radeon_firevertices(&rmesa
->radeon
);
1831 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1832 radeonUpdateScissor( ctx
);
1835 case GL_STENCIL_TEST
:
1836 if ( rmesa
->radeon
.state
.stencil
.hwBuffer
) {
1837 RADEON_STATECHANGE( rmesa
, ctx
);
1839 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1841 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1844 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1848 case GL_TEXTURE_GEN_Q
:
1849 case GL_TEXTURE_GEN_R
:
1850 case GL_TEXTURE_GEN_S
:
1851 case GL_TEXTURE_GEN_T
:
1852 /* Picked up in radeonUpdateTextureState.
1854 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1857 case GL_COLOR_SUM_EXT
:
1858 radeonUpdateSpecular ( ctx
);
1867 static void radeonLightingSpaceChange( GLcontext
*ctx
)
1869 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1871 RADEON_STATECHANGE( rmesa
, tcl
);
1873 if (RADEON_DEBUG
& DEBUG_STATE
)
1874 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1875 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1877 if (ctx
->_NeedEyeCoords
)
1878 tmp
= ctx
->Transform
.RescaleNormals
;
1880 tmp
= !ctx
->Transform
.RescaleNormals
;
1883 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1885 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1888 if (RADEON_DEBUG
& DEBUG_STATE
)
1889 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1890 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1893 /* =============================================================
1894 * Deferred state management - matrices, textures, other?
1898 void radeonUploadTexMatrix( r100ContextPtr rmesa
,
1899 int unit
, GLboolean swapcols
)
1901 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1902 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1903 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1904 texgen generates all 4 coords, at least tests with projtex indicated that.
1905 So: if we need the q coord in the end (solely determined by the texture
1906 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1907 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1908 column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
1909 will get submitted in the "wrong", i.e. 3rd, slot.
1910 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1911 size and using the texture matrix to swap the r and q coords around (ut2k3
1912 does exactly that), so we don't need the 3rd / 4th column swap - still need
1913 the 3rd / 4th row swap of course. This will potentially break for apps which
1914 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1915 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1916 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1917 incredibly hard to detect so we can't just fallback in such a case. Assume
1918 it never happens... - rs
1921 int idx
= TEXMAT_0
+ unit
;
1922 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
1924 struct gl_texture_unit tUnit
= rmesa
->radeon
.glCtx
->Texture
.Unit
[unit
];
1925 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
1927 rmesa
->TexMatColSwap
&= ~(1 << unit
);
1928 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
1930 rmesa
->TexMatColSwap
|= 1 << unit
;
1931 /* attention some elems are swapped 2 times! */
1944 /* those last 4 are probably never used */
1951 for (i
= 0; i
< 2; i
++) {
1955 *dest
++ = src
[i
+12];
1957 for (i
= 3; i
>= 2; i
--) {
1961 *dest
++ = src
[i
+12];
1966 for (i
= 0 ; i
< 4 ; i
++) {
1970 *dest
++ = src
[i
+12];
1974 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1978 static void upload_matrix( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1980 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1984 for (i
= 0 ; i
< 4 ; i
++) {
1988 *dest
++ = src
[i
+12];
1991 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1994 static void upload_matrix_t( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1996 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1997 memcpy(dest
, src
, 16*sizeof(float));
1998 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
2002 static void update_texturematrix( GLcontext
*ctx
)
2004 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
2005 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
2006 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
2008 GLuint texMatEnabled
= 0;
2009 rmesa
->NeedTexMatrix
= 0;
2010 rmesa
->TexMatColSwap
= 0;
2012 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
2013 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
2014 GLboolean needMatrix
= GL_FALSE
;
2015 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
2016 needMatrix
= GL_TRUE
;
2017 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
2018 RADEON_TEXMAT_0_ENABLE
) << unit
;
2020 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2021 /* Need to preconcatenate any active texgen
2022 * obj/eyeplane matrices:
2024 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
2025 ctx
->TextureMatrixStack
[unit
].Top
,
2026 &rmesa
->TexGenMatrix
[unit
] );
2029 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
2030 ctx
->TextureMatrixStack
[unit
].Top
);
2033 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2034 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
2035 needMatrix
= GL_TRUE
;
2038 rmesa
->NeedTexMatrix
|= 1 << unit
;
2039 radeonUploadTexMatrix( rmesa
, unit
,
2040 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
2045 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
2047 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2048 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2049 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
2050 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
2052 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
2053 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
2054 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
2055 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
2056 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
2057 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
2059 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2060 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2062 RADEON_STATECHANGE(rmesa
, tcl
);
2063 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2064 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2070 * Tell the card where to render (offset, pitch).
2071 * Effected by glDrawBuffer, etc
2074 radeonUpdateDrawBuffer(GLcontext
*ctx
)
2076 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2077 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
2078 struct radeon_renderbuffer
*rrb
;
2080 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
2082 rrb
= (void *) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
2083 } else if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
2085 rrb
= (void *) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
2087 /* drawing to multiple buffers, or none */
2094 RADEON_STATECHANGE( rmesa
, ctx
);
2098 void radeonValidateState( GLcontext
*ctx
)
2100 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2101 GLuint new_state
= rmesa
->radeon
.NewGLState
;
2103 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2104 radeonUpdateDrawBuffer(ctx
);
2107 if (new_state
& _NEW_TEXTURE
) {
2108 radeonUpdateTextureState( ctx
);
2109 new_state
|= rmesa
->radeon
.NewGLState
; /* may add TEXTURE_MATRIX */
2112 /* Need an event driven matrix update?
2114 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2115 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2117 /* Need these for lighting (shouldn't upload otherwise)
2119 if (new_state
& (_NEW_MODELVIEW
)) {
2120 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2121 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2124 /* Does this need to be triggered on eg. modelview for
2125 * texgen-derived objplane/eyeplane matrices?
2127 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2128 update_texturematrix( ctx
);
2131 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2132 update_light( ctx
);
2135 /* emit all active clip planes if projection matrix changes.
2137 if (new_state
& (_NEW_PROJECTION
)) {
2138 if (ctx
->Transform
.ClipPlanesEnabled
)
2139 radeonUpdateClipPlanes( ctx
);
2143 rmesa
->radeon
.NewGLState
= 0;
2147 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2149 _swrast_InvalidateState( ctx
, new_state
);
2150 _swsetup_InvalidateState( ctx
, new_state
);
2151 _vbo_InvalidateState( ctx
, new_state
);
2152 _tnl_InvalidateState( ctx
, new_state
);
2153 _ae_invalidate_state( ctx
, new_state
);
2154 R100_CONTEXT(ctx
)->radeon
.NewGLState
|= new_state
;
2158 /* A hack. Need a faster way to find this out.
2160 static GLboolean
check_material( GLcontext
*ctx
)
2162 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2165 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2166 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2168 if (tnl
->vb
.AttribPtr
[i
] &&
2169 tnl
->vb
.AttribPtr
[i
]->stride
)
2176 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2178 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2179 GLboolean has_material
;
2182 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->radeon
.NewGLState
);
2186 if (rmesa
->radeon
.NewGLState
)
2187 radeonValidateState( ctx
);
2189 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2192 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2195 /* Run the pipeline.
2197 _tnl_run_pipeline( ctx
);
2200 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2205 /* Initialize the driver's state functions.
2206 * Many of the ctx->Driver functions might have been initialized to
2207 * software defaults in the earlier _mesa_init_driver_functions() call.
2209 void radeonInitStateFuncs( GLcontext
*ctx
)
2211 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2212 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2214 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2215 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2217 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2218 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2219 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2220 ctx
->Driver
.ClearColor
= radeonClearColor
;
2221 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2222 ctx
->Driver
.ClearIndex
= NULL
;
2223 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2224 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2225 ctx
->Driver
.ColorMask
= radeonColorMask
;
2226 ctx
->Driver
.CullFace
= radeonCullFace
;
2227 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2228 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2229 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2230 ctx
->Driver
.Enable
= radeonEnable
;
2231 ctx
->Driver
.Fogfv
= radeonFogfv
;
2232 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2233 ctx
->Driver
.Hint
= NULL
;
2234 ctx
->Driver
.IndexMask
= NULL
;
2235 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2236 ctx
->Driver
.Lightfv
= radeonLightfv
;
2237 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2238 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2239 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2240 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2241 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2242 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2243 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2244 ctx
->Driver
.Scissor
= radeonScissor
;
2245 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2246 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2247 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2248 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2249 ctx
->Driver
.Viewport
= radeonViewport
;
2251 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2252 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;