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 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
532 float_ui32_type constant
= { units
* depthScale
};
533 float_ui32_type factoru
= { factor
};
535 RADEON_STATECHANGE( rmesa
, zbs
);
536 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
537 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
540 static void radeonPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
542 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
544 drm_radeon_stipple_t stipple
;
546 /* Must flip pattern upside down.
548 for ( i
= 0 ; i
< 32 ; i
++ ) {
549 rmesa
->state
.stipple
.mask
[31 - i
] = ((GLuint
*) mask
)[i
];
552 /* TODO: push this into cmd mechanism
554 radeon_firevertices(&rmesa
->radeon
);
555 LOCK_HARDWARE( &rmesa
->radeon
);
557 /* FIXME: Use window x,y offsets into stipple RAM.
559 stipple
.mask
= rmesa
->state
.stipple
.mask
;
560 drmCommandWrite( rmesa
->radeon
.dri
.fd
, DRM_RADEON_STIPPLE
,
561 &stipple
, sizeof(drm_radeon_stipple_t
) );
562 UNLOCK_HARDWARE( &rmesa
->radeon
);
565 static void radeonPolygonMode( GLcontext
*ctx
, GLenum face
, GLenum mode
)
567 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
568 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
570 /* Can't generally do unfilled via tcl, but some good special
573 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
574 if (rmesa
->radeon
.TclFallback
) {
575 radeonChooseRenderState( ctx
);
576 radeonChooseVertexState( ctx
);
581 /* =============================================================
582 * Rendering attributes
584 * We really don't want to recalculate all this every time we bind a
585 * texture. These things shouldn't change all that often, so it makes
586 * sense to break them out of the core texture state update routines.
589 /* Examine lighting and texture state to determine if separate specular
592 static void radeonUpdateSpecular( GLcontext
*ctx
)
594 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
595 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
598 RADEON_STATECHANGE( rmesa
, tcl
);
600 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
601 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
602 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
603 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
604 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
606 p
&= ~RADEON_SPECULAR_ENABLE
;
608 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
611 if (ctx
->Light
.Enabled
&&
612 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
613 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
614 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
615 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
616 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
617 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
618 p
|= RADEON_SPECULAR_ENABLE
;
619 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
620 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
622 else if (ctx
->Light
.Enabled
) {
623 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
624 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
625 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
626 } else if (ctx
->Fog
.ColorSumEnabled
) {
627 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
628 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
629 p
|= RADEON_SPECULAR_ENABLE
;
631 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
634 if (ctx
->Fog
.Enabled
) {
635 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
636 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
637 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
638 /* Bizzare: have to leave lighting enabled to get fog. */
639 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
642 /* cannot do tcl fog factor calculation with fog coord source
643 * (send precomputed factors). Cannot use precomputed fog
644 * factors together with tcl spec light (need tcl fallback) */
645 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
646 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
650 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
652 if (NEED_SECONDARY_COLOR(ctx
)) {
653 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
655 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
658 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
659 RADEON_STATECHANGE( rmesa
, ctx
);
660 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
663 /* Update vertex/render formats
665 if (rmesa
->radeon
.TclFallback
) {
666 radeonChooseRenderState( ctx
);
667 radeonChooseVertexState( ctx
);
672 /* =============================================================
677 /* Update on colormaterial, material emmissive/ambient,
678 * lightmodel.globalambient
680 static void update_global_ambient( GLcontext
*ctx
)
682 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
683 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
685 /* Need to do more if both emmissive & ambient are PREMULT:
686 * Hope this is not needed for MULT
688 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
689 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
690 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
692 COPY_3V( &fcmd
[GLT_RED
],
693 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
694 ACC_SCALE_3V( &fcmd
[GLT_RED
],
695 ctx
->Light
.Model
.Ambient
,
696 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
700 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
703 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
706 /* Update on change to
710 static void update_light_colors( GLcontext
*ctx
, GLuint p
)
712 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
714 /* fprintf(stderr, "%s\n", __FUNCTION__); */
717 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
718 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
720 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
721 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
722 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
724 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
728 /* Also fallback for asym colormaterial mode in twoside lighting...
730 static void check_twoside_fallback( GLcontext
*ctx
)
732 GLboolean fallback
= GL_FALSE
;
735 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
736 if (ctx
->Light
.ColorMaterialEnabled
&&
737 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
738 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
741 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
742 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
743 ctx
->Light
.Material
.Attrib
[i
+1],
744 sizeof(GLfloat
)*4) != 0) {
751 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
755 static void radeonColorMaterial( GLcontext
*ctx
, GLenum face
, GLenum mode
)
757 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
758 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
760 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
761 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
762 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
763 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
765 if (ctx
->Light
.ColorMaterialEnabled
) {
766 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
768 if (mask
& MAT_BIT_FRONT_EMISSION
) {
769 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
770 RADEON_EMISSIVE_SOURCE_SHIFT
);
773 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
774 RADEON_EMISSIVE_SOURCE_SHIFT
);
777 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
778 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
779 RADEON_AMBIENT_SOURCE_SHIFT
);
782 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
783 RADEON_AMBIENT_SOURCE_SHIFT
);
786 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
787 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
788 RADEON_DIFFUSE_SOURCE_SHIFT
);
791 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
792 RADEON_DIFFUSE_SOURCE_SHIFT
);
795 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
796 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
797 RADEON_SPECULAR_SOURCE_SHIFT
);
800 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
801 RADEON_SPECULAR_SOURCE_SHIFT
);
807 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
808 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
809 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
810 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
813 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
814 RADEON_STATECHANGE( rmesa
, tcl
);
815 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
819 void radeonUpdateMaterial( GLcontext
*ctx
)
821 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
822 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
823 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
826 if (ctx
->Light
.ColorMaterialEnabled
)
827 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
829 if (RADEON_DEBUG
& DEBUG_STATE
)
830 fprintf(stderr
, "%s\n", __FUNCTION__
);
833 if (mask
& MAT_BIT_FRONT_EMISSION
) {
834 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
835 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
836 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
837 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
839 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
840 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
841 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
842 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
843 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
845 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
846 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
847 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
848 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
849 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
851 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
852 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
853 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
854 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
855 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
857 if (mask
& MAT_BIT_FRONT_SHININESS
) {
858 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
861 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
863 check_twoside_fallback( ctx
);
864 /* update_global_ambient( ctx );*/
869 * _MESA_NEW_NEED_EYE_COORDS
871 * Uses derived state from mesa:
880 * which are calculated in light.c and are correct for the current
881 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
882 * and _MESA_NEW_NEED_EYE_COORDS.
884 static void update_light( GLcontext
*ctx
)
886 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
888 /* Have to check these, or have an automatic shortcircuit mechanism
889 * to remove noop statechanges. (Or just do a better job on the
893 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
895 if (ctx
->_NeedEyeCoords
)
896 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
898 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
901 /* Leave this test disabled: (unexplained q3 lockup) (even with
904 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
906 RADEON_STATECHANGE( rmesa
, tcl
);
907 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
912 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
913 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
914 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
915 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
916 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
917 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
922 if (ctx
->Light
.Enabled
) {
924 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
925 if (ctx
->Light
.Light
[p
].Enabled
) {
926 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
927 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
929 if (l
->EyePosition
[3] == 0.0) {
930 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
931 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
932 fcmd
[LIT_POSITION_W
] = 0;
933 fcmd
[LIT_DIRECTION_W
] = 0;
935 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
936 fcmd
[LIT_DIRECTION_X
] = -l
->_NormDirection
[0];
937 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormDirection
[1];
938 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormDirection
[2];
939 fcmd
[LIT_DIRECTION_W
] = 0;
942 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
948 static void radeonLightfv( GLcontext
*ctx
, GLenum light
,
949 GLenum pname
, const GLfloat
*params
)
951 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
952 GLint p
= light
- GL_LIGHT0
;
953 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
954 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
961 update_light_colors( ctx
, p
);
964 case GL_SPOT_DIRECTION
:
965 /* picked up in update_light */
969 /* positions picked up in update_light, but can do flag here */
971 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
973 /* FIXME: Set RANGE_ATTEN only when needed */
975 flag
= RADEON_LIGHT_1_IS_LOCAL
;
977 flag
= RADEON_LIGHT_0_IS_LOCAL
;
979 RADEON_STATECHANGE(rmesa
, tcl
);
980 if (l
->EyePosition
[3] != 0.0F
)
981 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
983 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
987 case GL_SPOT_EXPONENT
:
988 RADEON_STATECHANGE(rmesa
, lit
[p
]);
989 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
992 case GL_SPOT_CUTOFF
: {
993 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
994 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
996 RADEON_STATECHANGE(rmesa
, lit
[p
]);
997 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
999 RADEON_STATECHANGE(rmesa
, tcl
);
1000 if (l
->SpotCutoff
!= 180.0F
)
1001 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
1003 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
1008 case GL_CONSTANT_ATTENUATION
:
1009 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1010 fcmd
[LIT_ATTEN_CONST
] = params
[0];
1011 if ( params
[0] == 0.0 )
1012 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
1014 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
1016 case GL_LINEAR_ATTENUATION
:
1017 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1018 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
1020 case GL_QUADRATIC_ATTENUATION
:
1021 RADEON_STATECHANGE(rmesa
, lit
[p
]);
1022 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1028 /* Set RANGE_ATTEN only when needed */
1031 case GL_CONSTANT_ATTENUATION
:
1032 case GL_LINEAR_ATTENUATION
:
1033 case GL_QUADRATIC_ATTENUATION
:
1035 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1036 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1037 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1038 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1039 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1040 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1042 if ( l
->EyePosition
[3] == 0.0F
||
1043 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1044 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1045 /* Disable attenuation */
1046 icmd
[idx
] &= ~atten_flag
;
1048 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1049 /* Enable only constant portion of attenuation calculation */
1050 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1052 /* Enable full attenuation calculation */
1053 icmd
[idx
] &= ~atten_const_flag
;
1054 icmd
[idx
] |= atten_flag
;
1058 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1069 static void radeonLightModelfv( GLcontext
*ctx
, GLenum pname
,
1070 const GLfloat
*param
)
1072 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1075 case GL_LIGHT_MODEL_AMBIENT
:
1076 update_global_ambient( ctx
);
1079 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1080 RADEON_STATECHANGE( rmesa
, tcl
);
1081 if (ctx
->Light
.Model
.LocalViewer
)
1082 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1084 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1087 case GL_LIGHT_MODEL_TWO_SIDE
:
1088 RADEON_STATECHANGE( rmesa
, tcl
);
1089 if (ctx
->Light
.Model
.TwoSide
)
1090 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1092 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1094 check_twoside_fallback( ctx
);
1096 if (rmesa
->radeon
.TclFallback
) {
1097 radeonChooseRenderState( ctx
);
1098 radeonChooseVertexState( ctx
);
1102 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1103 radeonUpdateSpecular(ctx
);
1111 static void radeonShadeModel( GLcontext
*ctx
, GLenum mode
)
1113 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1114 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1116 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1117 RADEON_ALPHA_SHADE_MASK
|
1118 RADEON_SPECULAR_SHADE_MASK
|
1119 RADEON_FOG_SHADE_MASK
);
1123 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1124 RADEON_ALPHA_SHADE_FLAT
|
1125 RADEON_SPECULAR_SHADE_FLAT
|
1126 RADEON_FOG_SHADE_FLAT
);
1129 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1130 RADEON_ALPHA_SHADE_GOURAUD
|
1131 RADEON_SPECULAR_SHADE_GOURAUD
|
1132 RADEON_FOG_SHADE_GOURAUD
);
1138 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1139 RADEON_STATECHANGE( rmesa
, set
);
1140 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1145 /* =============================================================
1149 static void radeonClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
1151 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1152 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1153 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1155 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1156 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1157 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1158 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1159 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1162 static void radeonUpdateClipPlanes( GLcontext
*ctx
)
1164 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1167 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1168 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1169 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1171 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1172 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1173 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1174 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1175 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1181 /* =============================================================
1186 radeonStencilFuncSeparate( GLcontext
*ctx
, GLenum face
, GLenum func
,
1187 GLint ref
, GLuint mask
)
1189 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1190 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << RADEON_STENCIL_REF_SHIFT
) |
1191 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1193 RADEON_STATECHANGE( rmesa
, ctx
);
1194 RADEON_STATECHANGE( rmesa
, msk
);
1196 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1197 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1198 RADEON_STENCIL_VALUE_MASK
);
1200 switch ( ctx
->Stencil
.Function
[0] ) {
1202 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1205 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1208 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1211 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1214 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1217 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1220 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1223 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1227 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1231 radeonStencilMaskSeparate( GLcontext
*ctx
, GLenum face
, GLuint mask
)
1233 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1235 RADEON_STATECHANGE( rmesa
, msk
);
1236 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1237 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1238 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1241 static void radeonStencilOpSeparate( GLcontext
*ctx
, GLenum face
, GLenum fail
,
1242 GLenum zfail
, GLenum zpass
)
1244 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1246 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1247 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1248 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1250 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1251 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1252 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1253 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1254 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1255 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1257 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1258 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1259 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1260 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1261 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1262 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1263 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1266 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1267 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1268 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1269 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1270 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1271 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1274 RADEON_STATECHANGE( rmesa
, ctx
);
1275 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1276 RADEON_STENCIL_ZFAIL_MASK
|
1277 RADEON_STENCIL_ZPASS_MASK
);
1279 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1281 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1284 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1287 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1290 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1293 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1296 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1299 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1306 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1308 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1311 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1314 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1317 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1320 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1323 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1326 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1329 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1333 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1335 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1338 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1341 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1344 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1347 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1350 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1353 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1356 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1361 static void radeonClearStencil( GLcontext
*ctx
, GLint s
)
1363 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1365 rmesa
->radeon
.state
.stencil
.clear
=
1366 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
1367 (0xff << RADEON_STENCIL_MASK_SHIFT
) |
1368 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
));
1372 /* =============================================================
1373 * Window position and viewport transformation
1377 * To correctly position primitives:
1379 #define SUBPIXEL_X 0.125
1380 #define SUBPIXEL_Y 0.125
1384 * Called when window size or position changes or viewport or depth range
1385 * state is changed. We update the hardware viewport state here.
1387 void radeonUpdateWindow( GLcontext
*ctx
)
1389 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1390 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1391 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
1392 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
1393 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1394 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
? (ctx
->DrawBuffer
->Name
!= 0) : 0);
1395 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1396 GLfloat y_scale
, y_bias
;
1398 if (render_to_fbo
) {
1406 float_ui32_type sx
= { v
[MAT_SX
] };
1407 float_ui32_type tx
= { v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
};
1408 float_ui32_type sy
= { v
[MAT_SY
] * y_scale
};
1409 float_ui32_type ty
= { (v
[MAT_TY
] * y_scale
) + y_bias
+ SUBPIXEL_Y
};
1410 float_ui32_type sz
= { v
[MAT_SZ
] * depthScale
};
1411 float_ui32_type tz
= { v
[MAT_TZ
] * depthScale
};
1413 RADEON_STATECHANGE( rmesa
, vpt
);
1415 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1416 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1417 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1418 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1419 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1420 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1424 static void radeonViewport( GLcontext
*ctx
, GLint x
, GLint y
,
1425 GLsizei width
, GLsizei height
)
1427 /* Don't pipeline viewport changes, conflict with window offset
1428 * setting below. Could apply deltas to rescue pipelined viewport
1429 * values, or keep the originals hanging around.
1431 radeonUpdateWindow( ctx
);
1433 radeon_viewport(ctx
, x
, y
, width
, height
);
1436 static void radeonDepthRange( GLcontext
*ctx
, GLclampd nearval
,
1439 radeonUpdateWindow( ctx
);
1442 void radeonUpdateViewportOffset( GLcontext
*ctx
)
1444 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1445 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1446 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
1447 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
1448 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1453 tx
.f
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1454 ty
.f
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1456 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != tx
.ui32
||
1457 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != ty
.ui32
)
1459 /* Note: this should also modify whatever data the context reset
1462 RADEON_STATECHANGE( rmesa
, vpt
);
1463 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1464 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1466 /* update polygon stipple x/y screen offset */
1469 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1471 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1472 RADEON_STIPPLE_Y_OFFSET_MASK
);
1474 /* add magic offsets, then invert */
1475 stx
= 31 - ((rmesa
->radeon
.dri
.drawable
->x
- 1) & RADEON_STIPPLE_COORD_MASK
);
1476 sty
= 31 - ((rmesa
->radeon
.dri
.drawable
->y
+ rmesa
->radeon
.dri
.drawable
->h
- 1)
1477 & RADEON_STIPPLE_COORD_MASK
);
1479 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1480 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1482 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1483 RADEON_STATECHANGE( rmesa
, msc
);
1484 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1489 radeonUpdateScissor( ctx
);
1494 /* =============================================================
1498 static void radeonClearColor( GLcontext
*ctx
, const GLfloat color
[4] )
1500 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1502 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
1503 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
1504 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
1505 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
1506 rmesa
->radeon
.state
.color
.clear
= radeonPackColor( rmesa
->radeon
.radeonScreen
->cpp
,
1507 c
[0], c
[1], c
[2], c
[3] );
1511 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
1513 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1514 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1518 static GLuint radeon_rop_tab
[] = {
1521 RADEON_ROP_AND_REVERSE
,
1523 RADEON_ROP_AND_INVERTED
,
1530 RADEON_ROP_OR_REVERSE
,
1531 RADEON_ROP_COPY_INVERTED
,
1532 RADEON_ROP_OR_INVERTED
,
1537 static void radeonLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
1539 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1540 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1544 RADEON_STATECHANGE( rmesa
, msk
);
1545 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1548 /* =============================================================
1549 * State enable/disable
1552 static void radeonEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1554 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1557 if ( RADEON_DEBUG
& DEBUG_STATE
)
1558 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1559 _mesa_lookup_enum_by_nr( cap
),
1560 state
? "GL_TRUE" : "GL_FALSE" );
1563 /* Fast track this one...
1571 RADEON_STATECHANGE( rmesa
, ctx
);
1573 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1575 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1580 RADEON_STATECHANGE( rmesa
, ctx
);
1582 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1584 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1586 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1587 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1588 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1590 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1593 /* Catch a possible fallback:
1596 ctx
->Driver
.BlendEquationSeparate( ctx
,
1597 ctx
->Color
.BlendEquationRGB
,
1598 ctx
->Color
.BlendEquationA
);
1599 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.BlendSrcRGB
,
1600 ctx
->Color
.BlendDstRGB
,
1601 ctx
->Color
.BlendSrcA
,
1602 ctx
->Color
.BlendDstA
);
1605 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1606 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1610 case GL_CLIP_PLANE0
:
1611 case GL_CLIP_PLANE1
:
1612 case GL_CLIP_PLANE2
:
1613 case GL_CLIP_PLANE3
:
1614 case GL_CLIP_PLANE4
:
1615 case GL_CLIP_PLANE5
:
1616 p
= cap
-GL_CLIP_PLANE0
;
1617 RADEON_STATECHANGE( rmesa
, tcl
);
1619 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1620 radeonClipPlane( ctx
, cap
, NULL
);
1623 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1627 case GL_COLOR_MATERIAL
:
1628 radeonColorMaterial( ctx
, 0, 0 );
1629 radeonUpdateMaterial( ctx
);
1633 radeonCullFace( ctx
, 0 );
1637 RADEON_STATECHANGE(rmesa
, ctx
);
1639 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1641 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1646 RADEON_STATECHANGE(rmesa
, ctx
);
1648 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1649 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->radeon
.state
.color
.roundEnable
;
1651 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1652 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->radeon
.state
.color
.roundEnable
;
1657 RADEON_STATECHANGE(rmesa
, ctx
);
1659 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1660 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1662 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1663 RADEON_STATECHANGE(rmesa
, tcl
);
1664 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1666 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1667 _mesa_allow_light_in_model( ctx
, !state
);
1678 RADEON_STATECHANGE(rmesa
, tcl
);
1679 p
= cap
- GL_LIGHT0
;
1681 flag
= (RADEON_LIGHT_1_ENABLE
|
1682 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1683 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1685 flag
= (RADEON_LIGHT_0_ENABLE
|
1686 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1687 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1690 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1692 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1696 update_light_colors( ctx
, p
);
1700 RADEON_STATECHANGE(rmesa
, tcl
);
1701 radeonUpdateSpecular(ctx
);
1702 check_twoside_fallback( ctx
);
1705 case GL_LINE_SMOOTH
:
1706 RADEON_STATECHANGE( rmesa
, ctx
);
1708 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1710 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1714 case GL_LINE_STIPPLE
:
1715 RADEON_STATECHANGE( rmesa
, ctx
);
1717 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1719 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1723 case GL_COLOR_LOGIC_OP
:
1724 RADEON_STATECHANGE( rmesa
, ctx
);
1725 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1726 && ctx
->Color
.BlendEquationRGB
== GL_LOGIC_OP
)) ) {
1727 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1729 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1734 RADEON_STATECHANGE( rmesa
, tcl
);
1736 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1738 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1742 case GL_POLYGON_OFFSET_POINT
:
1743 RADEON_STATECHANGE( rmesa
, set
);
1745 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1747 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1751 case GL_POLYGON_OFFSET_LINE
:
1752 RADEON_STATECHANGE( rmesa
, set
);
1754 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1756 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1760 case GL_POLYGON_OFFSET_FILL
:
1761 RADEON_STATECHANGE( rmesa
, set
);
1763 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1765 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1769 case GL_POLYGON_SMOOTH
:
1770 RADEON_STATECHANGE( rmesa
, ctx
);
1772 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1774 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1778 case GL_POLYGON_STIPPLE
:
1779 RADEON_STATECHANGE(rmesa
, ctx
);
1781 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1783 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1787 case GL_RESCALE_NORMAL_EXT
: {
1788 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1789 RADEON_STATECHANGE( rmesa
, tcl
);
1791 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1793 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1798 case GL_SCISSOR_TEST
:
1799 radeon_firevertices(&rmesa
->radeon
);
1800 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1801 radeonUpdateScissor( ctx
);
1804 case GL_STENCIL_TEST
:
1806 GLboolean hw_stencil
= GL_FALSE
;
1807 if (ctx
->DrawBuffer
) {
1808 struct radeon_renderbuffer
*rrbStencil
1809 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
1810 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
1814 RADEON_STATECHANGE( rmesa
, ctx
);
1816 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1818 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1821 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1826 case GL_TEXTURE_GEN_Q
:
1827 case GL_TEXTURE_GEN_R
:
1828 case GL_TEXTURE_GEN_S
:
1829 case GL_TEXTURE_GEN_T
:
1830 /* Picked up in radeonUpdateTextureState.
1832 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1835 case GL_COLOR_SUM_EXT
:
1836 radeonUpdateSpecular ( ctx
);
1845 static void radeonLightingSpaceChange( GLcontext
*ctx
)
1847 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1849 RADEON_STATECHANGE( rmesa
, tcl
);
1851 if (RADEON_DEBUG
& DEBUG_STATE
)
1852 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1853 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1855 if (ctx
->_NeedEyeCoords
)
1856 tmp
= ctx
->Transform
.RescaleNormals
;
1858 tmp
= !ctx
->Transform
.RescaleNormals
;
1861 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1863 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1866 if (RADEON_DEBUG
& DEBUG_STATE
)
1867 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1868 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1871 /* =============================================================
1872 * Deferred state management - matrices, textures, other?
1876 void radeonUploadTexMatrix( r100ContextPtr rmesa
,
1877 int unit
, GLboolean swapcols
)
1879 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1880 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1881 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1882 texgen generates all 4 coords, at least tests with projtex indicated that.
1883 So: if we need the q coord in the end (solely determined by the texture
1884 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1885 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1886 column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
1887 will get submitted in the "wrong", i.e. 3rd, slot.
1888 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1889 size and using the texture matrix to swap the r and q coords around (ut2k3
1890 does exactly that), so we don't need the 3rd / 4th column swap - still need
1891 the 3rd / 4th row swap of course. This will potentially break for apps which
1892 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1893 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1894 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1895 incredibly hard to detect so we can't just fallback in such a case. Assume
1896 it never happens... - rs
1899 int idx
= TEXMAT_0
+ unit
;
1900 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
1902 struct gl_texture_unit tUnit
= rmesa
->radeon
.glCtx
->Texture
.Unit
[unit
];
1903 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
1905 rmesa
->TexMatColSwap
&= ~(1 << unit
);
1906 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
1908 rmesa
->TexMatColSwap
|= 1 << unit
;
1909 /* attention some elems are swapped 2 times! */
1922 /* those last 4 are probably never used */
1929 for (i
= 0; i
< 2; i
++) {
1933 *dest
++ = src
[i
+12];
1935 for (i
= 3; i
>= 2; i
--) {
1939 *dest
++ = src
[i
+12];
1944 for (i
= 0 ; i
< 4 ; i
++) {
1948 *dest
++ = src
[i
+12];
1952 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1956 static void upload_matrix( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1958 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1962 for (i
= 0 ; i
< 4 ; i
++) {
1966 *dest
++ = src
[i
+12];
1969 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1972 static void upload_matrix_t( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1974 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1975 memcpy(dest
, src
, 16*sizeof(float));
1976 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1980 static void update_texturematrix( GLcontext
*ctx
)
1982 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
1983 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
1984 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
1986 GLuint texMatEnabled
= 0;
1987 rmesa
->NeedTexMatrix
= 0;
1988 rmesa
->TexMatColSwap
= 0;
1990 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
1991 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
1992 GLboolean needMatrix
= GL_FALSE
;
1993 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
1994 needMatrix
= GL_TRUE
;
1995 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
1996 RADEON_TEXMAT_0_ENABLE
) << unit
;
1998 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1999 /* Need to preconcatenate any active texgen
2000 * obj/eyeplane matrices:
2002 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
2003 ctx
->TextureMatrixStack
[unit
].Top
,
2004 &rmesa
->TexGenMatrix
[unit
] );
2007 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
2008 ctx
->TextureMatrixStack
[unit
].Top
);
2011 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
2012 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
2013 needMatrix
= GL_TRUE
;
2016 rmesa
->NeedTexMatrix
|= 1 << unit
;
2017 radeonUploadTexMatrix( rmesa
, unit
,
2018 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
2023 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
2025 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2026 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
2027 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
2028 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
2030 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
2031 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
2032 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
2033 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
2034 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
2035 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
2037 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
2038 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
2040 RADEON_STATECHANGE(rmesa
, tcl
);
2041 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
2042 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
2047 void radeonValidateState( GLcontext
*ctx
)
2049 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2050 GLuint new_state
= rmesa
->radeon
.NewGLState
;
2052 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2053 _mesa_update_framebuffer(ctx
);
2054 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2055 _mesa_update_draw_buffer_bounds(ctx
);
2056 RADEON_STATECHANGE(rmesa
, ctx
);
2059 if (new_state
& _NEW_TEXTURE
) {
2060 radeonUpdateTextureState( ctx
);
2061 new_state
|= rmesa
->radeon
.NewGLState
; /* may add TEXTURE_MATRIX */
2064 /* Need an event driven matrix update?
2066 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2067 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2069 /* Need these for lighting (shouldn't upload otherwise)
2071 if (new_state
& (_NEW_MODELVIEW
)) {
2072 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2073 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2076 /* Does this need to be triggered on eg. modelview for
2077 * texgen-derived objplane/eyeplane matrices?
2079 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2080 update_texturematrix( ctx
);
2083 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2084 update_light( ctx
);
2087 /* emit all active clip planes if projection matrix changes.
2089 if (new_state
& (_NEW_PROJECTION
)) {
2090 if (ctx
->Transform
.ClipPlanesEnabled
)
2091 radeonUpdateClipPlanes( ctx
);
2095 rmesa
->radeon
.NewGLState
= 0;
2099 static void radeonInvalidateState( GLcontext
*ctx
, GLuint new_state
)
2101 _swrast_InvalidateState( ctx
, new_state
);
2102 _swsetup_InvalidateState( ctx
, new_state
);
2103 _vbo_InvalidateState( ctx
, new_state
);
2104 _tnl_InvalidateState( ctx
, new_state
);
2105 _ae_invalidate_state( ctx
, new_state
);
2106 R100_CONTEXT(ctx
)->radeon
.NewGLState
|= new_state
;
2110 /* A hack. Need a faster way to find this out.
2112 static GLboolean
check_material( GLcontext
*ctx
)
2114 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2117 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2118 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2120 if (tnl
->vb
.AttribPtr
[i
] &&
2121 tnl
->vb
.AttribPtr
[i
]->stride
)
2128 static void radeonWrapRunPipeline( GLcontext
*ctx
)
2130 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2131 GLboolean has_material
;
2134 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->radeon
.NewGLState
);
2138 if (rmesa
->radeon
.NewGLState
)
2139 radeonValidateState( ctx
);
2141 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2144 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2147 /* Run the pipeline.
2149 _tnl_run_pipeline( ctx
);
2152 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2157 /* Initialize the driver's state functions.
2158 * Many of the ctx->Driver functions might have been initialized to
2159 * software defaults in the earlier _mesa_init_driver_functions() call.
2161 void radeonInitStateFuncs( GLcontext
*ctx
)
2163 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2164 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2166 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2167 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2169 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2170 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2171 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2172 ctx
->Driver
.ClearColor
= radeonClearColor
;
2173 ctx
->Driver
.ClearDepth
= radeonClearDepth
;
2174 ctx
->Driver
.ClearIndex
= NULL
;
2175 ctx
->Driver
.ClearStencil
= radeonClearStencil
;
2176 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2177 ctx
->Driver
.ColorMask
= radeonColorMask
;
2178 ctx
->Driver
.CullFace
= radeonCullFace
;
2179 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2180 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2181 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2182 ctx
->Driver
.Enable
= radeonEnable
;
2183 ctx
->Driver
.Fogfv
= radeonFogfv
;
2184 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2185 ctx
->Driver
.Hint
= NULL
;
2186 ctx
->Driver
.IndexMask
= NULL
;
2187 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2188 ctx
->Driver
.Lightfv
= radeonLightfv
;
2189 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2190 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2191 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2192 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2193 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2194 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2195 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2196 ctx
->Driver
.Scissor
= radeonScissor
;
2197 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2198 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2199 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2200 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2201 ctx
->Driver
.Viewport
= radeonViewport
;
2203 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2204 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;