1 /**************************************************************************
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/fbobject.h"
43 #include "main/simple_list.h"
44 #include "main/state.h"
48 #include "tnl/t_pipeline.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "drivers/common/meta.h"
52 #include "radeon_context.h"
53 #include "radeon_mipmap_tree.h"
54 #include "radeon_ioctl.h"
55 #include "radeon_state.h"
56 #include "radeon_tcl.h"
57 #include "radeon_tex.h"
58 #include "radeon_swtcl.h"
60 static void radeonUpdateSpecular( struct gl_context
*ctx
);
62 /* =============================================================
66 static void radeonAlphaFunc( struct gl_context
*ctx
, GLenum func
, GLfloat ref
)
68 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
69 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
72 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
74 RADEON_STATECHANGE( rmesa
, ctx
);
76 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
77 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
81 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
84 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
87 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
90 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
93 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
96 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
99 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
102 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
106 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
109 static void radeonBlendEquationSeparate( struct gl_context
*ctx
,
110 GLenum modeRGB
, GLenum modeA
)
112 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
113 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
114 GLboolean fallback
= GL_FALSE
;
116 assert( modeRGB
== modeA
);
121 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
124 case GL_FUNC_SUBTRACT
:
125 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
129 if (ctx
->Color
.BlendEnabled
)
132 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
136 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
138 RADEON_STATECHANGE( rmesa
, ctx
);
139 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
140 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
141 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
142 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
144 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
149 static void radeonBlendFuncSeparate( struct gl_context
*ctx
,
150 GLenum sfactorRGB
, GLenum dfactorRGB
,
151 GLenum sfactorA
, GLenum dfactorA
)
153 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
154 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
155 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
156 GLboolean fallback
= GL_FALSE
;
158 switch ( ctx
->Color
.Blend
[0].SrcRGB
) {
160 b
|= RADEON_SRC_BLEND_GL_ZERO
;
163 b
|= RADEON_SRC_BLEND_GL_ONE
;
166 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
168 case GL_ONE_MINUS_DST_COLOR
:
169 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
172 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
174 case GL_ONE_MINUS_SRC_COLOR
:
175 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
178 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
180 case GL_ONE_MINUS_SRC_ALPHA
:
181 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
184 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
186 case GL_ONE_MINUS_DST_ALPHA
:
187 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
189 case GL_SRC_ALPHA_SATURATE
:
190 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
192 case GL_CONSTANT_COLOR
:
193 case GL_ONE_MINUS_CONSTANT_COLOR
:
194 case GL_CONSTANT_ALPHA
:
195 case GL_ONE_MINUS_CONSTANT_ALPHA
:
196 if (ctx
->Color
.BlendEnabled
)
199 b
|= RADEON_SRC_BLEND_GL_ONE
;
205 switch ( ctx
->Color
.Blend
[0].DstRGB
) {
207 b
|= RADEON_DST_BLEND_GL_ZERO
;
210 b
|= RADEON_DST_BLEND_GL_ONE
;
213 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
215 case GL_ONE_MINUS_SRC_COLOR
:
216 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
219 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
221 case GL_ONE_MINUS_SRC_ALPHA
:
222 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
225 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
227 case GL_ONE_MINUS_DST_COLOR
:
228 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
231 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
233 case GL_ONE_MINUS_DST_ALPHA
:
234 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
236 case GL_CONSTANT_COLOR
:
237 case GL_ONE_MINUS_CONSTANT_COLOR
:
238 case GL_CONSTANT_ALPHA
:
239 case GL_ONE_MINUS_CONSTANT_ALPHA
:
240 if (ctx
->Color
.BlendEnabled
)
243 b
|= RADEON_DST_BLEND_GL_ZERO
;
249 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
251 RADEON_STATECHANGE( rmesa
, ctx
);
252 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
257 /* =============================================================
261 static void radeonDepthFunc( struct gl_context
*ctx
, GLenum func
)
263 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
265 RADEON_STATECHANGE( rmesa
, ctx
);
266 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
268 switch ( ctx
->Depth
.Func
) {
270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
291 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
297 static void radeonDepthMask( struct gl_context
*ctx
, GLboolean flag
)
299 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
300 RADEON_STATECHANGE( rmesa
, ctx
);
302 if ( ctx
->Depth
.Mask
) {
303 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
305 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
310 /* =============================================================
315 static void radeonFogfv( struct gl_context
*ctx
, GLenum pname
, const GLfloat
*param
)
317 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
318 union { int i
; float f
; } c
, d
;
323 if (!ctx
->Fog
.Enabled
)
325 RADEON_STATECHANGE(rmesa
, tcl
);
326 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
327 switch (ctx
->Fog
.Mode
) {
329 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
332 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
335 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
344 if (!ctx
->Fog
.Enabled
)
346 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
347 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
348 switch (ctx
->Fog
.Mode
) {
351 /* While this is the opposite sign from the DDK, it makes the fog test
352 * pass, and matches r200.
354 d
.f
= -ctx
->Fog
.Density
;
358 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
361 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
365 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
366 /* While this is the opposite sign from the DDK, it makes the fog
367 * test pass, and matches r200.
369 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
375 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
376 RADEON_STATECHANGE( rmesa
, fog
);
377 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
378 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
382 RADEON_STATECHANGE( rmesa
, ctx
);
383 _mesa_unclamped_float_rgba_to_ubyte(col
, ctx
->Fog
.Color
);
384 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
385 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
386 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
388 case GL_FOG_COORD_SRC
:
389 radeonUpdateSpecular( ctx
);
396 /* =============================================================
400 static void radeonCullFace( struct gl_context
*ctx
, GLenum unused
)
402 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
403 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
404 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
406 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
407 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
409 if ( ctx
->Polygon
.CullFlag
) {
410 switch ( ctx
->Polygon
.CullFaceMode
) {
412 s
&= ~RADEON_FFACE_SOLID
;
413 t
|= RADEON_CULL_FRONT
;
416 s
&= ~RADEON_BFACE_SOLID
;
417 t
|= RADEON_CULL_BACK
;
419 case GL_FRONT_AND_BACK
:
420 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
421 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
426 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
427 RADEON_STATECHANGE(rmesa
, set
);
428 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
431 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
432 RADEON_STATECHANGE(rmesa
, tcl
);
433 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
437 static void radeonFrontFace( struct gl_context
*ctx
, GLenum mode
)
439 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
441 RADEON_STATECHANGE( rmesa
, set
);
442 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
444 RADEON_STATECHANGE( rmesa
, tcl
);
445 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
447 /* Winding is inverted when rendering to FBO */
448 if (ctx
->DrawBuffer
&& _mesa_is_user_fbo(ctx
->DrawBuffer
))
449 mode
= (mode
== GL_CW
) ? GL_CCW
: GL_CW
;
453 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CW
;
456 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_FFACE_CULL_CCW
;
457 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
463 /* =============================================================
466 static void radeonLineWidth( struct gl_context
*ctx
, GLfloat widthf
)
468 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
470 RADEON_STATECHANGE( rmesa
, lin
);
471 RADEON_STATECHANGE( rmesa
, set
);
473 /* Line width is stored in U6.4 format.
475 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
476 if ( widthf
> 1.0 ) {
477 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
479 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
483 static void radeonLineStipple( struct gl_context
*ctx
, GLint factor
, GLushort pattern
)
485 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
487 RADEON_STATECHANGE( rmesa
, lin
);
488 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
489 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
493 /* =============================================================
496 static void radeonColorMask( struct gl_context
*ctx
,
497 GLboolean r
, GLboolean g
,
498 GLboolean b
, GLboolean a
)
500 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
501 struct radeon_renderbuffer
*rrb
;
504 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
508 mask
= radeonPackColor( rrb
->cpp
,
509 ctx
->Color
.ColorMask
[0][RCOMP
],
510 ctx
->Color
.ColorMask
[0][GCOMP
],
511 ctx
->Color
.ColorMask
[0][BCOMP
],
512 ctx
->Color
.ColorMask
[0][ACOMP
] );
514 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
515 RADEON_STATECHANGE( rmesa
, msk
);
516 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
521 /* =============================================================
525 static void radeonPolygonOffset( struct gl_context
*ctx
,
526 GLfloat factor
, GLfloat units
)
528 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
529 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
530 float_ui32_type constant
= { units
* depthScale
};
531 float_ui32_type factoru
= { factor
};
533 RADEON_STATECHANGE( rmesa
, zbs
);
534 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
535 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
538 static void radeonPolygonMode( struct gl_context
*ctx
, GLenum face
, GLenum mode
)
540 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
541 GLboolean flag
= (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
) != 0;
543 /* Can't generally do unfilled via tcl, but some good special
546 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, flag
);
547 if (rmesa
->radeon
.TclFallback
) {
548 radeonChooseRenderState( ctx
);
549 radeonChooseVertexState( ctx
);
554 /* =============================================================
555 * Rendering attributes
557 * We really don't want to recalculate all this every time we bind a
558 * texture. These things shouldn't change all that often, so it makes
559 * sense to break them out of the core texture state update routines.
562 /* Examine lighting and texture state to determine if separate specular
565 static void radeonUpdateSpecular( struct gl_context
*ctx
)
567 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
568 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
571 RADEON_STATECHANGE( rmesa
, tcl
);
573 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
574 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
575 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
576 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
577 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
579 p
&= ~RADEON_SPECULAR_ENABLE
;
581 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
584 if (ctx
->Light
.Enabled
&&
585 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
586 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
587 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
588 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
589 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
590 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
591 p
|= RADEON_SPECULAR_ENABLE
;
592 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
593 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
595 else if (ctx
->Light
.Enabled
) {
596 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
597 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
598 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
599 } else if (ctx
->Fog
.ColorSumEnabled
) {
600 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
601 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
602 p
|= RADEON_SPECULAR_ENABLE
;
604 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
607 if (ctx
->Fog
.Enabled
) {
608 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
609 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
610 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
611 /* Bizzare: have to leave lighting enabled to get fog. */
612 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
615 /* cannot do tcl fog factor calculation with fog coord source
616 * (send precomputed factors). Cannot use precomputed fog
617 * factors together with tcl spec light (need tcl fallback) */
618 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
619 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
623 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
625 if (_mesa_need_secondary_color(ctx
)) {
626 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
628 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
631 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
632 RADEON_STATECHANGE( rmesa
, ctx
);
633 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
636 /* Update vertex/render formats
638 if (rmesa
->radeon
.TclFallback
) {
639 radeonChooseRenderState( ctx
);
640 radeonChooseVertexState( ctx
);
645 /* =============================================================
650 /* Update on colormaterial, material emmissive/ambient,
651 * lightmodel.globalambient
653 static void update_global_ambient( struct gl_context
*ctx
)
655 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
656 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
658 /* Need to do more if both emmissive & ambient are PREMULT:
659 * Hope this is not needed for MULT
661 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
662 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
663 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
665 COPY_3V( &fcmd
[GLT_RED
],
666 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
667 ACC_SCALE_3V( &fcmd
[GLT_RED
],
668 ctx
->Light
.Model
.Ambient
,
669 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
673 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
676 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
679 /* Update on change to
683 static void update_light_colors( struct gl_context
*ctx
, GLuint p
)
685 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
687 /* fprintf(stderr, "%s\n", __FUNCTION__); */
690 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
691 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
693 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
694 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
695 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
697 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
701 /* Also fallback for asym colormaterial mode in twoside lighting...
703 static void check_twoside_fallback( struct gl_context
*ctx
)
705 GLboolean fallback
= GL_FALSE
;
708 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
709 if (ctx
->Light
.ColorMaterialEnabled
&&
710 (ctx
->Light
.ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
711 ((ctx
->Light
.ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
714 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
715 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
716 ctx
->Light
.Material
.Attrib
[i
+1],
717 sizeof(GLfloat
)*4) != 0) {
724 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
728 static void radeonColorMaterial( struct gl_context
*ctx
, GLenum face
, GLenum mode
)
730 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
731 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
733 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
734 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
735 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
736 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
738 if (ctx
->Light
.ColorMaterialEnabled
) {
739 GLuint mask
= ctx
->Light
.ColorMaterialBitmask
;
741 if (mask
& MAT_BIT_FRONT_EMISSION
) {
742 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
743 RADEON_EMISSIVE_SOURCE_SHIFT
);
746 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
747 RADEON_EMISSIVE_SOURCE_SHIFT
);
750 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
751 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
752 RADEON_AMBIENT_SOURCE_SHIFT
);
755 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
756 RADEON_AMBIENT_SOURCE_SHIFT
);
759 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
760 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
761 RADEON_DIFFUSE_SOURCE_SHIFT
);
764 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
765 RADEON_DIFFUSE_SOURCE_SHIFT
);
768 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
769 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
770 RADEON_SPECULAR_SOURCE_SHIFT
);
773 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
774 RADEON_SPECULAR_SOURCE_SHIFT
);
780 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
781 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
782 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
783 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
786 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
787 RADEON_STATECHANGE( rmesa
, tcl
);
788 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
792 void radeonUpdateMaterial( struct gl_context
*ctx
)
794 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
795 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
796 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
799 if (ctx
->Light
.ColorMaterialEnabled
)
800 mask
&= ~ctx
->Light
.ColorMaterialBitmask
;
802 if (RADEON_DEBUG
& RADEON_STATE
)
803 fprintf(stderr
, "%s\n", __FUNCTION__
);
806 if (mask
& MAT_BIT_FRONT_EMISSION
) {
807 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
808 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
809 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
810 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
812 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
813 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
814 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
815 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
816 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
818 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
819 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
820 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
821 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
822 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
824 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
825 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
826 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
827 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
828 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
830 if (mask
& MAT_BIT_FRONT_SHININESS
) {
831 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
834 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
836 check_twoside_fallback( ctx
);
837 /* update_global_ambient( ctx );*/
842 * _MESA_NEW_NEED_EYE_COORDS
844 * Uses derived state from mesa:
853 * which are calculated in light.c and are correct for the current
854 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
855 * and _MESA_NEW_NEED_EYE_COORDS.
857 static void update_light( struct gl_context
*ctx
)
859 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
861 /* Have to check these, or have an automatic shortcircuit mechanism
862 * to remove noop statechanges. (Or just do a better job on the
866 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
868 if (ctx
->_NeedEyeCoords
)
869 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
871 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
874 /* Leave this test disabled: (unexplained q3 lockup) (even with
877 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
879 RADEON_STATECHANGE( rmesa
, tcl
);
880 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
885 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
886 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
887 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
888 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
889 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
890 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
895 if (ctx
->Light
.Enabled
) {
897 for (p
= 0 ; p
< MAX_LIGHTS
; p
++) {
898 if (ctx
->Light
.Light
[p
].Enabled
) {
899 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
900 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
902 if (l
->EyePosition
[3] == 0.0) {
903 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
904 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
905 fcmd
[LIT_POSITION_W
] = 0;
906 fcmd
[LIT_DIRECTION_W
] = 0;
908 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
909 fcmd
[LIT_DIRECTION_X
] = -l
->_NormSpotDirection
[0];
910 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormSpotDirection
[1];
911 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormSpotDirection
[2];
912 fcmd
[LIT_DIRECTION_W
] = 0;
915 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
921 static void radeonLightfv( struct gl_context
*ctx
, GLenum light
,
922 GLenum pname
, const GLfloat
*params
)
924 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
925 GLint p
= light
- GL_LIGHT0
;
926 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
927 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
934 update_light_colors( ctx
, p
);
937 case GL_SPOT_DIRECTION
:
938 /* picked up in update_light */
942 /* positions picked up in update_light, but can do flag here */
944 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
946 /* FIXME: Set RANGE_ATTEN only when needed */
948 flag
= RADEON_LIGHT_1_IS_LOCAL
;
950 flag
= RADEON_LIGHT_0_IS_LOCAL
;
952 RADEON_STATECHANGE(rmesa
, tcl
);
953 if (l
->EyePosition
[3] != 0.0F
)
954 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
956 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
960 case GL_SPOT_EXPONENT
:
961 RADEON_STATECHANGE(rmesa
, lit
[p
]);
962 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
965 case GL_SPOT_CUTOFF
: {
966 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
967 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
969 RADEON_STATECHANGE(rmesa
, lit
[p
]);
970 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
972 RADEON_STATECHANGE(rmesa
, tcl
);
973 if (l
->SpotCutoff
!= 180.0F
)
974 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
976 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
981 case GL_CONSTANT_ATTENUATION
:
982 RADEON_STATECHANGE(rmesa
, lit
[p
]);
983 fcmd
[LIT_ATTEN_CONST
] = params
[0];
984 if ( params
[0] == 0.0 )
985 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
987 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
989 case GL_LINEAR_ATTENUATION
:
990 RADEON_STATECHANGE(rmesa
, lit
[p
]);
991 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
993 case GL_QUADRATIC_ATTENUATION
:
994 RADEON_STATECHANGE(rmesa
, lit
[p
]);
995 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1001 /* Set RANGE_ATTEN only when needed */
1004 case GL_CONSTANT_ATTENUATION
:
1005 case GL_LINEAR_ATTENUATION
:
1006 case GL_QUADRATIC_ATTENUATION
:
1008 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1009 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1010 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1011 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1012 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1013 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1015 if ( l
->EyePosition
[3] == 0.0F
||
1016 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1017 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1018 /* Disable attenuation */
1019 icmd
[idx
] &= ~atten_flag
;
1021 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1022 /* Enable only constant portion of attenuation calculation */
1023 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1025 /* Enable full attenuation calculation */
1026 icmd
[idx
] &= ~atten_const_flag
;
1027 icmd
[idx
] |= atten_flag
;
1031 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1042 static void radeonLightModelfv( struct gl_context
*ctx
, GLenum pname
,
1043 const GLfloat
*param
)
1045 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1048 case GL_LIGHT_MODEL_AMBIENT
:
1049 update_global_ambient( ctx
);
1052 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1053 RADEON_STATECHANGE( rmesa
, tcl
);
1054 if (ctx
->Light
.Model
.LocalViewer
)
1055 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1057 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1060 case GL_LIGHT_MODEL_TWO_SIDE
:
1061 RADEON_STATECHANGE( rmesa
, tcl
);
1062 if (ctx
->Light
.Model
.TwoSide
)
1063 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1065 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1067 check_twoside_fallback( ctx
);
1069 if (rmesa
->radeon
.TclFallback
) {
1070 radeonChooseRenderState( ctx
);
1071 radeonChooseVertexState( ctx
);
1075 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1076 radeonUpdateSpecular(ctx
);
1084 static void radeonShadeModel( struct gl_context
*ctx
, GLenum mode
)
1086 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1087 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1089 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1090 RADEON_ALPHA_SHADE_MASK
|
1091 RADEON_SPECULAR_SHADE_MASK
|
1092 RADEON_FOG_SHADE_MASK
);
1096 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1097 RADEON_ALPHA_SHADE_FLAT
|
1098 RADEON_SPECULAR_SHADE_FLAT
|
1099 RADEON_FOG_SHADE_FLAT
);
1102 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1103 RADEON_ALPHA_SHADE_GOURAUD
|
1104 RADEON_SPECULAR_SHADE_GOURAUD
|
1105 RADEON_FOG_SHADE_GOURAUD
);
1111 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1112 RADEON_STATECHANGE( rmesa
, set
);
1113 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1118 /* =============================================================
1122 static void radeonClipPlane( struct gl_context
*ctx
, GLenum plane
, const GLfloat
*eq
)
1124 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1125 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1126 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1128 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1129 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1130 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1131 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1132 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1135 static void radeonUpdateClipPlanes( struct gl_context
*ctx
)
1137 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1140 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1141 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1142 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1144 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1145 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1146 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1147 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1148 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1154 /* =============================================================
1159 radeonStencilFuncSeparate( struct gl_context
*ctx
, GLenum face
, GLenum func
,
1160 GLint ref
, GLuint mask
)
1162 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1163 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << RADEON_STENCIL_REF_SHIFT
) |
1164 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1166 RADEON_STATECHANGE( rmesa
, ctx
);
1167 RADEON_STATECHANGE( rmesa
, msk
);
1169 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1170 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1171 RADEON_STENCIL_VALUE_MASK
);
1173 switch ( ctx
->Stencil
.Function
[0] ) {
1175 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1178 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1181 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1184 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1187 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1190 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1193 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1196 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1200 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1204 radeonStencilMaskSeparate( struct gl_context
*ctx
, GLenum face
, GLuint mask
)
1206 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1208 RADEON_STATECHANGE( rmesa
, msk
);
1209 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1210 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1211 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1214 static void radeonStencilOpSeparate( struct gl_context
*ctx
, GLenum face
, GLenum fail
,
1215 GLenum zfail
, GLenum zpass
)
1217 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1219 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1220 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1221 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1223 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1224 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1225 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1226 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1227 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1228 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1230 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1231 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1232 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1233 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1234 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1235 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1236 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1239 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1240 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1241 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1242 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1243 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1244 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1247 RADEON_STATECHANGE( rmesa
, ctx
);
1248 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1249 RADEON_STENCIL_ZFAIL_MASK
|
1250 RADEON_STENCIL_ZPASS_MASK
);
1252 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1254 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1257 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1260 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1263 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1266 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1269 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1272 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1275 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1279 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1281 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1284 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1287 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1290 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1293 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1296 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1299 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1302 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1306 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1308 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1311 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1314 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1317 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1320 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1323 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1326 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1329 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1336 /* =============================================================
1337 * Window position and viewport transformation
1341 * To correctly position primitives:
1343 #define SUBPIXEL_X 0.125
1344 #define SUBPIXEL_Y 0.125
1348 * Called when window size or position changes or viewport or depth range
1349 * state is changed. We update the hardware viewport state here.
1351 void radeonUpdateWindow( struct gl_context
*ctx
)
1353 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1354 __DRIdrawable
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1355 GLfloat xoffset
= 0.0;
1356 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->h
: 0;
1357 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1358 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
? _mesa_is_user_fbo(ctx
->DrawBuffer
) : 0);
1359 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1360 GLfloat y_scale
, y_bias
;
1362 if (render_to_fbo
) {
1370 float_ui32_type sx
= { v
[MAT_SX
] };
1371 float_ui32_type tx
= { v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
};
1372 float_ui32_type sy
= { v
[MAT_SY
] * y_scale
};
1373 float_ui32_type ty
= { (v
[MAT_TY
] * y_scale
) + y_bias
+ SUBPIXEL_Y
};
1374 float_ui32_type sz
= { v
[MAT_SZ
] * depthScale
};
1375 float_ui32_type tz
= { v
[MAT_TZ
] * depthScale
};
1377 RADEON_STATECHANGE( rmesa
, vpt
);
1379 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1380 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1381 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1382 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1383 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1384 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1388 static void radeonViewport( struct gl_context
*ctx
, GLint x
, GLint y
,
1389 GLsizei width
, GLsizei height
)
1391 /* Don't pipeline viewport changes, conflict with window offset
1392 * setting below. Could apply deltas to rescue pipelined viewport
1393 * values, or keep the originals hanging around.
1395 radeonUpdateWindow( ctx
);
1397 radeon_viewport(ctx
, x
, y
, width
, height
);
1400 static void radeonDepthRange( struct gl_context
*ctx
, GLclampd nearval
,
1403 radeonUpdateWindow( ctx
);
1406 void radeonUpdateViewportOffset( struct gl_context
*ctx
)
1408 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1409 __DRIdrawable
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1410 GLfloat xoffset
= 0.0;
1411 GLfloat yoffset
= (GLfloat
)dPriv
->h
;
1412 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1417 tx
.f
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1418 ty
.f
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1420 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != tx
.ui32
||
1421 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != ty
.ui32
)
1423 /* Note: this should also modify whatever data the context reset
1426 RADEON_STATECHANGE( rmesa
, vpt
);
1427 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1428 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1430 /* update polygon stipple x/y screen offset */
1433 GLuint m
= rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
];
1435 m
&= ~(RADEON_STIPPLE_X_OFFSET_MASK
|
1436 RADEON_STIPPLE_Y_OFFSET_MASK
);
1438 /* add magic offsets, then invert */
1439 stx
= 31 - ((-1) & RADEON_STIPPLE_COORD_MASK
);
1440 sty
= 31 - ((dPriv
->h
- 1)
1441 & RADEON_STIPPLE_COORD_MASK
);
1443 m
|= ((stx
<< RADEON_STIPPLE_X_OFFSET_SHIFT
) |
1444 (sty
<< RADEON_STIPPLE_Y_OFFSET_SHIFT
));
1446 if ( rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] != m
) {
1447 RADEON_STATECHANGE( rmesa
, msc
);
1448 rmesa
->hw
.msc
.cmd
[MSC_RE_MISC
] = m
;
1453 radeonUpdateScissor( ctx
);
1458 /* =============================================================
1462 static void radeonRenderMode( struct gl_context
*ctx
, GLenum mode
)
1464 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1465 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1469 static GLuint radeon_rop_tab
[] = {
1472 RADEON_ROP_AND_REVERSE
,
1474 RADEON_ROP_AND_INVERTED
,
1481 RADEON_ROP_OR_REVERSE
,
1482 RADEON_ROP_COPY_INVERTED
,
1483 RADEON_ROP_OR_INVERTED
,
1488 static void radeonLogicOpCode( struct gl_context
*ctx
, GLenum opcode
)
1490 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1491 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1495 RADEON_STATECHANGE( rmesa
, msk
);
1496 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1499 /* =============================================================
1500 * State enable/disable
1503 static void radeonEnable( struct gl_context
*ctx
, GLenum cap
, GLboolean state
)
1505 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1508 if ( RADEON_DEBUG
& RADEON_STATE
)
1509 fprintf( stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1510 _mesa_lookup_enum_by_nr( cap
),
1511 state
? "GL_TRUE" : "GL_FALSE" );
1514 /* Fast track this one...
1522 RADEON_STATECHANGE( rmesa
, ctx
);
1524 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1526 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1531 RADEON_STATECHANGE( rmesa
, ctx
);
1533 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1535 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1537 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1538 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1539 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1541 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1544 /* Catch a possible fallback:
1547 ctx
->Driver
.BlendEquationSeparate( ctx
,
1548 ctx
->Color
.Blend
[0].EquationRGB
,
1549 ctx
->Color
.Blend
[0].EquationA
);
1550 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.Blend
[0].SrcRGB
,
1551 ctx
->Color
.Blend
[0].DstRGB
,
1552 ctx
->Color
.Blend
[0].SrcA
,
1553 ctx
->Color
.Blend
[0].DstA
);
1556 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1557 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1561 case GL_CLIP_PLANE0
:
1562 case GL_CLIP_PLANE1
:
1563 case GL_CLIP_PLANE2
:
1564 case GL_CLIP_PLANE3
:
1565 case GL_CLIP_PLANE4
:
1566 case GL_CLIP_PLANE5
:
1567 p
= cap
-GL_CLIP_PLANE0
;
1568 RADEON_STATECHANGE( rmesa
, tcl
);
1570 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1571 radeonClipPlane( ctx
, cap
, NULL
);
1574 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1578 case GL_COLOR_MATERIAL
:
1579 radeonColorMaterial( ctx
, 0, 0 );
1580 radeonUpdateMaterial( ctx
);
1584 radeonCullFace( ctx
, 0 );
1588 RADEON_STATECHANGE(rmesa
, ctx
);
1590 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1592 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1597 RADEON_STATECHANGE(rmesa
, ctx
);
1599 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1600 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->radeon
.state
.color
.roundEnable
;
1602 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1603 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->radeon
.state
.color
.roundEnable
;
1608 RADEON_STATECHANGE(rmesa
, ctx
);
1610 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1611 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1613 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1614 RADEON_STATECHANGE(rmesa
, tcl
);
1615 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1617 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1618 _mesa_allow_light_in_model( ctx
, !state
);
1629 RADEON_STATECHANGE(rmesa
, tcl
);
1630 p
= cap
- GL_LIGHT0
;
1632 flag
= (RADEON_LIGHT_1_ENABLE
|
1633 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1634 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1636 flag
= (RADEON_LIGHT_0_ENABLE
|
1637 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1638 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1641 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1643 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1647 update_light_colors( ctx
, p
);
1651 RADEON_STATECHANGE(rmesa
, tcl
);
1652 radeonUpdateSpecular(ctx
);
1653 check_twoside_fallback( ctx
);
1656 case GL_LINE_SMOOTH
:
1657 RADEON_STATECHANGE( rmesa
, ctx
);
1659 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1661 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1665 case GL_LINE_STIPPLE
:
1666 RADEON_STATECHANGE( rmesa
, ctx
);
1668 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1670 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1674 case GL_COLOR_LOGIC_OP
:
1675 RADEON_STATECHANGE( rmesa
, ctx
);
1676 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1677 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1678 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1680 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1685 RADEON_STATECHANGE( rmesa
, tcl
);
1687 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1689 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1693 case GL_POLYGON_OFFSET_POINT
:
1694 RADEON_STATECHANGE( rmesa
, set
);
1696 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1698 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1702 case GL_POLYGON_OFFSET_LINE
:
1703 RADEON_STATECHANGE( rmesa
, set
);
1705 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1707 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1711 case GL_POLYGON_OFFSET_FILL
:
1712 RADEON_STATECHANGE( rmesa
, set
);
1714 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1716 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1720 case GL_POLYGON_SMOOTH
:
1721 RADEON_STATECHANGE( rmesa
, ctx
);
1723 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1725 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1729 case GL_POLYGON_STIPPLE
:
1730 RADEON_STATECHANGE(rmesa
, ctx
);
1732 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1734 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1738 case GL_RESCALE_NORMAL_EXT
: {
1739 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1740 RADEON_STATECHANGE( rmesa
, tcl
);
1742 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1744 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1749 case GL_SCISSOR_TEST
:
1750 radeon_firevertices(&rmesa
->radeon
);
1751 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1752 radeonUpdateScissor( ctx
);
1755 case GL_STENCIL_TEST
:
1757 GLboolean hw_stencil
= GL_FALSE
;
1758 if (ctx
->DrawBuffer
) {
1759 struct radeon_renderbuffer
*rrbStencil
1760 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
1761 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
1765 RADEON_STATECHANGE( rmesa
, ctx
);
1767 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1769 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1772 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1777 case GL_TEXTURE_GEN_Q
:
1778 case GL_TEXTURE_GEN_R
:
1779 case GL_TEXTURE_GEN_S
:
1780 case GL_TEXTURE_GEN_T
:
1781 /* Picked up in radeonUpdateTextureState.
1783 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1786 case GL_COLOR_SUM_EXT
:
1787 radeonUpdateSpecular ( ctx
);
1796 static void radeonLightingSpaceChange( struct gl_context
*ctx
)
1798 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1800 RADEON_STATECHANGE( rmesa
, tcl
);
1802 if (RADEON_DEBUG
& RADEON_STATE
)
1803 fprintf(stderr
, "%s %d BEFORE %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1804 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1806 if (ctx
->_NeedEyeCoords
)
1807 tmp
= ctx
->Transform
.RescaleNormals
;
1809 tmp
= !ctx
->Transform
.RescaleNormals
;
1812 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1814 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1817 if (RADEON_DEBUG
& RADEON_STATE
)
1818 fprintf(stderr
, "%s %d AFTER %x\n", __FUNCTION__
, ctx
->_NeedEyeCoords
,
1819 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1822 /* =============================================================
1823 * Deferred state management - matrices, textures, other?
1827 void radeonUploadTexMatrix( r100ContextPtr rmesa
,
1828 int unit
, GLboolean swapcols
)
1830 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1831 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1832 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1833 texgen generates all 4 coords, at least tests with projtex indicated that.
1834 So: if we need the q coord in the end (solely determined by the texture
1835 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1836 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1837 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1838 will get submitted in the "wrong", i.e. 3rd, slot.
1839 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1840 size and using the texture matrix to swap the r and q coords around (ut2k3
1841 does exactly that), so we don't need the 3rd / 4th column swap - still need
1842 the 3rd / 4th row swap of course. This will potentially break for apps which
1843 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1844 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1845 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1846 incredibly hard to detect so we can't just fallback in such a case. Assume
1847 it never happens... - rs
1850 int idx
= TEXMAT_0
+ unit
;
1851 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
1853 struct gl_texture_unit tUnit
= rmesa
->radeon
.glCtx
->Texture
.Unit
[unit
];
1854 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
1856 rmesa
->TexMatColSwap
&= ~(1 << unit
);
1857 if ((tUnit
._ReallyEnabled
& (TEXTURE_3D_BIT
| TEXTURE_CUBE_BIT
)) == 0) {
1859 rmesa
->TexMatColSwap
|= 1 << unit
;
1860 /* attention some elems are swapped 2 times! */
1873 /* those last 4 are probably never used */
1880 for (i
= 0; i
< 2; i
++) {
1884 *dest
++ = src
[i
+12];
1886 for (i
= 3; i
>= 2; i
--) {
1890 *dest
++ = src
[i
+12];
1895 for (i
= 0 ; i
< 4 ; i
++) {
1899 *dest
++ = src
[i
+12];
1903 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1907 static void upload_matrix( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1909 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1913 for (i
= 0 ; i
< 4 ; i
++) {
1917 *dest
++ = src
[i
+12];
1920 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1923 static void upload_matrix_t( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1925 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1926 memcpy(dest
, src
, 16*sizeof(float));
1927 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1931 static void update_texturematrix( struct gl_context
*ctx
)
1933 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
1934 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
1935 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
1937 GLuint texMatEnabled
= 0;
1938 rmesa
->NeedTexMatrix
= 0;
1939 rmesa
->TexMatColSwap
= 0;
1941 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
1942 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
1943 GLboolean needMatrix
= GL_FALSE
;
1944 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
1945 needMatrix
= GL_TRUE
;
1946 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
1947 RADEON_TEXMAT_0_ENABLE
) << unit
;
1949 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1950 /* Need to preconcatenate any active texgen
1951 * obj/eyeplane matrices:
1953 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
1954 ctx
->TextureMatrixStack
[unit
].Top
,
1955 &rmesa
->TexGenMatrix
[unit
] );
1958 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
1959 ctx
->TextureMatrixStack
[unit
].Top
);
1962 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1963 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
1964 needMatrix
= GL_TRUE
;
1967 rmesa
->NeedTexMatrix
|= 1 << unit
;
1968 radeonUploadTexMatrix( rmesa
, unit
,
1969 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
1974 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
1976 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1977 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
1978 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
1979 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
1981 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
1982 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
1983 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
1984 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
1985 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
1986 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
1988 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
1989 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
1991 RADEON_STATECHANGE(rmesa
, tcl
);
1992 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
1993 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
1997 static GLboolean
r100ValidateBuffers(struct gl_context
*ctx
)
1999 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2000 struct radeon_renderbuffer
*rrb
;
2003 radeon_cs_space_reset_bos(rmesa
->radeon
.cmdbuf
.cs
);
2005 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
2007 if (rrb
&& rrb
->bo
) {
2008 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
2009 0, RADEON_GEM_DOMAIN_VRAM
);
2013 rrb
= radeon_get_depthbuffer(&rmesa
->radeon
);
2015 if (rrb
&& rrb
->bo
) {
2016 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
2017 0, RADEON_GEM_DOMAIN_VRAM
);
2020 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; ++i
) {
2023 if (!ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2026 t
= rmesa
->state
.texture
.unit
[i
].texobj
;
2030 if (t
->image_override
&& t
->bo
)
2031 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->bo
,
2032 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
2034 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->mt
->bo
,
2035 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
2038 ret
= radeon_cs_space_check_with_bo(rmesa
->radeon
.cmdbuf
.cs
, first_elem(&rmesa
->radeon
.dma
.reserved
)->bo
, RADEON_GEM_DOMAIN_GTT
, 0);
2044 GLboolean
radeonValidateState( struct gl_context
*ctx
)
2046 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2047 GLuint new_state
= rmesa
->radeon
.NewGLState
;
2049 if (new_state
& _NEW_BUFFERS
) {
2050 _mesa_update_framebuffer(ctx
);
2051 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2052 _mesa_update_draw_buffer_bounds(ctx
);
2053 RADEON_STATECHANGE(rmesa
, ctx
);
2056 if (new_state
& _NEW_TEXTURE
) {
2057 radeonUpdateTextureState( ctx
);
2058 new_state
|= rmesa
->radeon
.NewGLState
; /* may add TEXTURE_MATRIX */
2061 /* we need to do a space check here */
2062 if (!r100ValidateBuffers(ctx
))
2065 /* Need an event driven matrix update?
2067 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2068 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2070 /* Need these for lighting (shouldn't upload otherwise)
2072 if (new_state
& (_NEW_MODELVIEW
)) {
2073 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2074 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2077 /* Does this need to be triggered on eg. modelview for
2078 * texgen-derived objplane/eyeplane matrices?
2080 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2081 update_texturematrix( ctx
);
2084 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2085 update_light( ctx
);
2088 /* emit all active clip planes if projection matrix changes.
2090 if (new_state
& (_NEW_PROJECTION
)) {
2091 if (ctx
->Transform
.ClipPlanesEnabled
)
2092 radeonUpdateClipPlanes( ctx
);
2096 rmesa
->radeon
.NewGLState
= 0;
2102 static void radeonInvalidateState( struct gl_context
*ctx
, GLuint new_state
)
2104 _swrast_InvalidateState( ctx
, new_state
);
2105 _swsetup_InvalidateState( ctx
, new_state
);
2106 _vbo_InvalidateState( ctx
, new_state
);
2107 _tnl_InvalidateState( ctx
, new_state
);
2108 _ae_invalidate_state( ctx
, new_state
);
2109 R100_CONTEXT(ctx
)->radeon
.NewGLState
|= new_state
;
2113 /* A hack. Need a faster way to find this out.
2115 static GLboolean
check_material( struct gl_context
*ctx
)
2117 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2120 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2121 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2123 if (tnl
->vb
.AttribPtr
[i
] &&
2124 tnl
->vb
.AttribPtr
[i
]->stride
)
2131 static void radeonWrapRunPipeline( struct gl_context
*ctx
)
2133 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2134 GLboolean has_material
;
2137 fprintf(stderr
, "%s, newstate: %x\n", __FUNCTION__
, rmesa
->radeon
.NewGLState
);
2141 if (rmesa
->radeon
.NewGLState
)
2142 if (!radeonValidateState( ctx
))
2143 FALLBACK(rmesa
, RADEON_FALLBACK_TEXTURE
, GL_TRUE
);
2145 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2148 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2151 /* Run the pipeline.
2153 _tnl_run_pipeline( ctx
);
2156 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2160 static void radeonPolygonStipple( struct gl_context
*ctx
, const GLubyte
*mask
)
2162 r100ContextPtr r100
= R100_CONTEXT(ctx
);
2165 radeon_firevertices(&r100
->radeon
);
2167 RADEON_STATECHANGE(r100
, stp
);
2169 /* Must flip pattern upside down.
2171 for ( i
= 31 ; i
>= 0; i
--) {
2172 r100
->hw
.stp
.cmd
[3 + i
] = ((GLuint
*) mask
)[i
];
2177 /* Initialize the driver's state functions.
2178 * Many of the ctx->Driver functions might have been initialized to
2179 * software defaults in the earlier _mesa_init_driver_functions() call.
2181 void radeonInitStateFuncs( struct gl_context
*ctx
)
2183 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2184 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2186 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2187 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2188 ctx
->Driver
.CopyPixels
= _mesa_meta_CopyPixels
;
2189 ctx
->Driver
.DrawPixels
= _mesa_meta_DrawPixels
;
2190 ctx
->Driver
.ReadPixels
= radeonReadPixels
;
2192 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2193 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2194 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2195 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2196 ctx
->Driver
.ColorMask
= radeonColorMask
;
2197 ctx
->Driver
.CullFace
= radeonCullFace
;
2198 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2199 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2200 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2201 ctx
->Driver
.Enable
= radeonEnable
;
2202 ctx
->Driver
.Fogfv
= radeonFogfv
;
2203 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2204 ctx
->Driver
.Hint
= NULL
;
2205 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2206 ctx
->Driver
.Lightfv
= radeonLightfv
;
2207 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2208 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2209 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2210 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2211 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2212 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2213 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2214 ctx
->Driver
.Scissor
= radeonScissor
;
2215 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2216 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2217 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2218 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2219 ctx
->Driver
.Viewport
= radeonViewport
;
2221 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2222 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;