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 <keithw@vmware.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 "util/simple_list.h"
44 #include "main/state.h"
45 #include "main/core.h"
46 #include "main/stencil.h"
47 #include "main/viewport.h"
51 #include "tnl/t_pipeline.h"
52 #include "swrast_setup/swrast_setup.h"
53 #include "drivers/common/meta.h"
54 #include "util/bitscan.h"
56 #include "radeon_context.h"
57 #include "radeon_mipmap_tree.h"
58 #include "radeon_ioctl.h"
59 #include "radeon_state.h"
60 #include "radeon_tcl.h"
61 #include "radeon_tex.h"
62 #include "radeon_swtcl.h"
64 static void radeonUpdateSpecular( struct gl_context
*ctx
);
66 /* =============================================================
70 static void radeonAlphaFunc( struct gl_context
*ctx
, GLenum func
, GLfloat ref
)
72 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
73 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
76 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
78 RADEON_STATECHANGE( rmesa
, ctx
);
80 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
81 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
85 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
88 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
91 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
94 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
97 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
100 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
103 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
106 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
110 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
113 static void radeonBlendEquationSeparate( struct gl_context
*ctx
,
114 GLenum modeRGB
, GLenum modeA
)
116 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
117 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
118 GLboolean fallback
= GL_FALSE
;
120 assert( modeRGB
== modeA
);
125 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
128 case GL_FUNC_SUBTRACT
:
129 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
133 if (ctx
->Color
.BlendEnabled
)
136 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
140 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
142 RADEON_STATECHANGE( rmesa
, ctx
);
143 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
144 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
145 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
146 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
148 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
153 static void radeonBlendFuncSeparate( struct gl_context
*ctx
,
154 GLenum sfactorRGB
, GLenum dfactorRGB
,
155 GLenum sfactorA
, GLenum dfactorA
)
157 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
158 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
159 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
160 GLboolean fallback
= GL_FALSE
;
162 switch ( ctx
->Color
.Blend
[0].SrcRGB
) {
164 b
|= RADEON_SRC_BLEND_GL_ZERO
;
167 b
|= RADEON_SRC_BLEND_GL_ONE
;
170 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
172 case GL_ONE_MINUS_DST_COLOR
:
173 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
176 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
178 case GL_ONE_MINUS_SRC_COLOR
:
179 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
182 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
184 case GL_ONE_MINUS_SRC_ALPHA
:
185 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
188 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
190 case GL_ONE_MINUS_DST_ALPHA
:
191 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
193 case GL_SRC_ALPHA_SATURATE
:
194 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
196 case GL_CONSTANT_COLOR
:
197 case GL_ONE_MINUS_CONSTANT_COLOR
:
198 case GL_CONSTANT_ALPHA
:
199 case GL_ONE_MINUS_CONSTANT_ALPHA
:
200 if (ctx
->Color
.BlendEnabled
)
203 b
|= RADEON_SRC_BLEND_GL_ONE
;
209 switch ( ctx
->Color
.Blend
[0].DstRGB
) {
211 b
|= RADEON_DST_BLEND_GL_ZERO
;
214 b
|= RADEON_DST_BLEND_GL_ONE
;
217 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
219 case GL_ONE_MINUS_SRC_COLOR
:
220 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
223 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
225 case GL_ONE_MINUS_SRC_ALPHA
:
226 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
229 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
231 case GL_ONE_MINUS_DST_COLOR
:
232 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
235 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
237 case GL_ONE_MINUS_DST_ALPHA
:
238 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
240 case GL_CONSTANT_COLOR
:
241 case GL_ONE_MINUS_CONSTANT_COLOR
:
242 case GL_CONSTANT_ALPHA
:
243 case GL_ONE_MINUS_CONSTANT_ALPHA
:
244 if (ctx
->Color
.BlendEnabled
)
247 b
|= RADEON_DST_BLEND_GL_ZERO
;
253 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
255 RADEON_STATECHANGE( rmesa
, ctx
);
256 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
261 /* =============================================================
265 static void radeonDepthFunc( struct gl_context
*ctx
, GLenum func
)
267 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
269 RADEON_STATECHANGE( rmesa
, ctx
);
270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
272 switch ( ctx
->Depth
.Func
) {
274 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
277 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
280 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
283 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
286 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
289 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
292 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
295 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
301 static void radeonDepthMask( struct gl_context
*ctx
, GLboolean flag
)
303 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
304 RADEON_STATECHANGE( rmesa
, ctx
);
306 if ( ctx
->Depth
.Mask
) {
307 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
309 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
314 /* =============================================================
319 static void radeonFogfv( struct gl_context
*ctx
, GLenum pname
, const GLfloat
*param
)
321 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
322 union { int i
; float f
; } c
, d
;
327 if (!ctx
->Fog
.Enabled
)
329 RADEON_STATECHANGE(rmesa
, tcl
);
330 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
331 switch (ctx
->Fog
.Mode
) {
333 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
336 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
339 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
348 if (!ctx
->Fog
.Enabled
)
350 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
351 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
352 switch (ctx
->Fog
.Mode
) {
355 /* While this is the opposite sign from the DDK, it makes the fog test
356 * pass, and matches r200.
358 d
.f
= -ctx
->Fog
.Density
;
362 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
365 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
369 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
370 /* While this is the opposite sign from the DDK, it makes the fog
371 * test pass, and matches r200.
373 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
379 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
380 RADEON_STATECHANGE( rmesa
, fog
);
381 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
382 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
386 RADEON_STATECHANGE( rmesa
, ctx
);
387 _mesa_unclamped_float_rgba_to_ubyte(col
, ctx
->Fog
.Color
);
388 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
389 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
390 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
392 case GL_FOG_COORD_SRC
:
393 radeonUpdateSpecular( ctx
);
400 /* =============================================================
404 static void radeonCullFace( struct gl_context
*ctx
, GLenum unused
)
406 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
407 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
408 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
410 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
411 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
413 if ( ctx
->Polygon
.CullFlag
) {
414 switch ( ctx
->Polygon
.CullFaceMode
) {
416 s
&= ~RADEON_FFACE_SOLID
;
417 t
|= RADEON_CULL_FRONT
;
420 s
&= ~RADEON_BFACE_SOLID
;
421 t
|= RADEON_CULL_BACK
;
423 case GL_FRONT_AND_BACK
:
424 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
425 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
430 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
431 RADEON_STATECHANGE(rmesa
, set
);
432 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
435 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
436 RADEON_STATECHANGE(rmesa
, tcl
);
437 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
441 static void radeonFrontFace( struct gl_context
*ctx
, GLenum mode
)
443 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
444 int cull_face
= (mode
== GL_CW
) ? RADEON_FFACE_CULL_CW
: RADEON_FFACE_CULL_CCW
;
446 RADEON_STATECHANGE( rmesa
, set
);
447 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
449 RADEON_STATECHANGE( rmesa
, tcl
);
450 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
452 /* Winding is inverted when rendering to FBO */
453 if (ctx
->DrawBuffer
&& _mesa_is_user_fbo(ctx
->DrawBuffer
))
454 cull_face
= (mode
== GL_CCW
) ? RADEON_FFACE_CULL_CW
: RADEON_FFACE_CULL_CCW
;
455 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= cull_face
;
457 if ( mode
== GL_CCW
)
458 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
462 /* =============================================================
465 static void radeonLineWidth( struct gl_context
*ctx
, GLfloat widthf
)
467 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
469 RADEON_STATECHANGE( rmesa
, lin
);
470 RADEON_STATECHANGE( rmesa
, set
);
472 /* Line width is stored in U6.4 format.
474 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
475 if ( widthf
> 1.0 ) {
476 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
478 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
482 static void radeonLineStipple( struct gl_context
*ctx
, GLint factor
, GLushort pattern
)
484 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
486 RADEON_STATECHANGE( rmesa
, lin
);
487 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
488 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
492 /* =============================================================
495 static void radeonColorMask( struct gl_context
*ctx
,
496 GLboolean r
, GLboolean g
,
497 GLboolean b
, GLboolean a
)
499 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
500 struct radeon_renderbuffer
*rrb
;
503 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
507 mask
= radeonPackColor( rrb
->cpp
,
508 ctx
->Color
.ColorMask
[0][RCOMP
],
509 ctx
->Color
.ColorMask
[0][GCOMP
],
510 ctx
->Color
.ColorMask
[0][BCOMP
],
511 ctx
->Color
.ColorMask
[0][ACOMP
] );
513 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
514 RADEON_STATECHANGE( rmesa
, msk
);
515 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
520 /* =============================================================
524 static void radeonPolygonOffset( struct gl_context
*ctx
,
525 GLfloat factor
, GLfloat units
, GLfloat clamp
)
527 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
528 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
529 float_ui32_type constant
= { units
* depthScale
};
530 float_ui32_type factoru
= { factor
};
532 RADEON_STATECHANGE( rmesa
, zbs
);
533 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
534 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
537 static void radeonPolygonMode( struct gl_context
*ctx
, GLenum face
, GLenum mode
)
539 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
540 GLboolean unfilled
= (ctx
->Polygon
.FrontMode
!= GL_FILL
||
541 ctx
->Polygon
.BackMode
!= GL_FILL
);
543 /* Can't generally do unfilled via tcl, but some good special
546 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, unfilled
);
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", __func__); */
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", __func__
);
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
) {
896 GLbitfield mask
= ctx
->Light
._EnabledLights
;
898 const int p
= u_bit_scan(&mask
);
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
] );
920 static void radeonLightfv( struct gl_context
*ctx
, GLenum light
,
921 GLenum pname
, const GLfloat
*params
)
923 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
924 GLint p
= light
- GL_LIGHT0
;
925 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
926 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
933 update_light_colors( ctx
, p
);
936 case GL_SPOT_DIRECTION
:
937 /* picked up in update_light */
941 /* positions picked up in update_light, but can do flag here */
943 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
945 /* FIXME: Set RANGE_ATTEN only when needed */
947 flag
= RADEON_LIGHT_1_IS_LOCAL
;
949 flag
= RADEON_LIGHT_0_IS_LOCAL
;
951 RADEON_STATECHANGE(rmesa
, tcl
);
952 if (l
->EyePosition
[3] != 0.0F
)
953 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
955 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
959 case GL_SPOT_EXPONENT
:
960 RADEON_STATECHANGE(rmesa
, lit
[p
]);
961 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
964 case GL_SPOT_CUTOFF
: {
965 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
966 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
968 RADEON_STATECHANGE(rmesa
, lit
[p
]);
969 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
971 RADEON_STATECHANGE(rmesa
, tcl
);
972 if (l
->SpotCutoff
!= 180.0F
)
973 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
975 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
980 case GL_CONSTANT_ATTENUATION
:
981 RADEON_STATECHANGE(rmesa
, lit
[p
]);
982 fcmd
[LIT_ATTEN_CONST
] = params
[0];
983 if ( params
[0] == 0.0 )
984 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
986 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
988 case GL_LINEAR_ATTENUATION
:
989 RADEON_STATECHANGE(rmesa
, lit
[p
]);
990 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
992 case GL_QUADRATIC_ATTENUATION
:
993 RADEON_STATECHANGE(rmesa
, lit
[p
]);
994 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
1000 /* Set RANGE_ATTEN only when needed */
1003 case GL_CONSTANT_ATTENUATION
:
1004 case GL_LINEAR_ATTENUATION
:
1005 case GL_QUADRATIC_ATTENUATION
:
1007 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1008 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1009 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1010 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1011 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1012 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1014 if ( l
->EyePosition
[3] == 0.0F
||
1015 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1016 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1017 /* Disable attenuation */
1018 icmd
[idx
] &= ~atten_flag
;
1020 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1021 /* Enable only constant portion of attenuation calculation */
1022 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1024 /* Enable full attenuation calculation */
1025 icmd
[idx
] &= ~atten_const_flag
;
1026 icmd
[idx
] |= atten_flag
;
1030 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1041 static void radeonLightModelfv( struct gl_context
*ctx
, GLenum pname
,
1042 const GLfloat
*param
)
1044 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1047 case GL_LIGHT_MODEL_AMBIENT
:
1048 update_global_ambient( ctx
);
1051 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1052 RADEON_STATECHANGE( rmesa
, tcl
);
1053 if (ctx
->Light
.Model
.LocalViewer
)
1054 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1056 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1059 case GL_LIGHT_MODEL_TWO_SIDE
:
1060 RADEON_STATECHANGE( rmesa
, tcl
);
1061 if (ctx
->Light
.Model
.TwoSide
)
1062 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1064 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1066 check_twoside_fallback( ctx
);
1068 if (rmesa
->radeon
.TclFallback
) {
1069 radeonChooseRenderState( ctx
);
1070 radeonChooseVertexState( ctx
);
1074 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1075 radeonUpdateSpecular(ctx
);
1083 static void radeonShadeModel( struct gl_context
*ctx
, GLenum mode
)
1085 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1086 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1088 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1089 RADEON_ALPHA_SHADE_MASK
|
1090 RADEON_SPECULAR_SHADE_MASK
|
1091 RADEON_FOG_SHADE_MASK
);
1095 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1096 RADEON_ALPHA_SHADE_FLAT
|
1097 RADEON_SPECULAR_SHADE_FLAT
|
1098 RADEON_FOG_SHADE_FLAT
);
1101 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1102 RADEON_ALPHA_SHADE_GOURAUD
|
1103 RADEON_SPECULAR_SHADE_GOURAUD
|
1104 RADEON_FOG_SHADE_GOURAUD
);
1110 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1111 RADEON_STATECHANGE( rmesa
, set
);
1112 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1117 /* =============================================================
1121 static void radeonClipPlane( struct gl_context
*ctx
, GLenum plane
, const GLfloat
*eq
)
1123 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1124 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1125 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1127 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1128 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1129 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1130 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1131 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1134 static void radeonUpdateClipPlanes( struct gl_context
*ctx
)
1136 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1139 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
1140 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
1141 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1143 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1144 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1145 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1146 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1147 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1153 /* =============================================================
1158 radeonStencilFuncSeparate( struct gl_context
*ctx
, GLenum face
, GLenum func
,
1159 GLint ref
, GLuint mask
)
1161 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1162 GLuint refmask
= ((_mesa_get_stencil_ref(ctx
, 0) << RADEON_STENCIL_REF_SHIFT
) |
1163 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1165 RADEON_STATECHANGE( rmesa
, ctx
);
1166 RADEON_STATECHANGE( rmesa
, msk
);
1168 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1169 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1170 RADEON_STENCIL_VALUE_MASK
);
1172 switch ( ctx
->Stencil
.Function
[0] ) {
1174 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1177 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1180 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1183 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1186 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1189 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1192 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1195 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1199 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1203 radeonStencilMaskSeparate( struct gl_context
*ctx
, GLenum face
, GLuint mask
)
1205 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1207 RADEON_STATECHANGE( rmesa
, msk
);
1208 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1209 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1210 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1213 static void radeonStencilOpSeparate( struct gl_context
*ctx
, GLenum face
, GLenum fail
,
1214 GLenum zfail
, GLenum zpass
)
1216 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1218 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1219 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1220 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1222 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1223 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1224 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1225 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1226 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1227 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1229 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1230 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1231 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1232 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1233 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1234 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1235 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1238 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1239 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1240 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1241 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1242 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1243 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1246 RADEON_STATECHANGE( rmesa
, ctx
);
1247 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1248 RADEON_STENCIL_ZFAIL_MASK
|
1249 RADEON_STENCIL_ZPASS_MASK
);
1251 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1253 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1256 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1259 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1262 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1265 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1268 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1271 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1274 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1278 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1280 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1283 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1286 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1289 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1292 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1295 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1298 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1301 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1305 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1307 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1310 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1313 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1316 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1319 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1322 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1325 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1328 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1335 /* =============================================================
1336 * Window position and viewport transformation
1340 * To correctly position primitives:
1342 #define SUBPIXEL_X 0.125
1343 #define SUBPIXEL_Y 0.125
1347 * Called when window size or position changes or viewport or depth range
1348 * state is changed. We update the hardware viewport state here.
1350 void radeonUpdateWindow( struct gl_context
*ctx
)
1352 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1353 __DRIdrawable
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1354 GLfloat xoffset
= 0.0;
1355 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->h
: 0;
1356 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
? _mesa_is_user_fbo(ctx
->DrawBuffer
) : 0);
1357 float scale
[3], translate
[3];
1358 GLfloat y_scale
, y_bias
;
1360 if (render_to_fbo
) {
1368 _mesa_get_viewport_xform(ctx
, 0, scale
, translate
);
1369 float_ui32_type sx
= { scale
[0] };
1370 float_ui32_type sy
= { scale
[1] * y_scale
};
1371 float_ui32_type sz
= { scale
[2] };
1372 float_ui32_type tx
= { translate
[0] + xoffset
+ SUBPIXEL_X
};
1373 float_ui32_type ty
= { (translate
[1] * y_scale
) + y_bias
+ SUBPIXEL_Y
};
1374 float_ui32_type tz
= { translate
[2] };
1376 RADEON_STATECHANGE( rmesa
, vpt
);
1378 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1379 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1380 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1381 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1382 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1383 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1387 static void radeonViewport(struct gl_context
*ctx
)
1389 /* Don't pipeline viewport changes, conflict with window offset
1390 * setting below. Could apply deltas to rescue pipelined viewport
1391 * values, or keep the originals hanging around.
1393 radeonUpdateWindow( ctx
);
1395 radeon_viewport(ctx
);
1398 static void radeonDepthRange(struct gl_context
*ctx
)
1400 radeonUpdateWindow( ctx
);
1403 /* =============================================================
1407 static void radeonRenderMode( struct gl_context
*ctx
, GLenum mode
)
1409 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1410 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1414 static GLuint radeon_rop_tab
[] = {
1417 RADEON_ROP_AND_REVERSE
,
1419 RADEON_ROP_AND_INVERTED
,
1426 RADEON_ROP_OR_REVERSE
,
1427 RADEON_ROP_COPY_INVERTED
,
1428 RADEON_ROP_OR_INVERTED
,
1433 static void radeonLogicOpCode( struct gl_context
*ctx
, GLenum opcode
)
1435 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1436 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1440 RADEON_STATECHANGE( rmesa
, msk
);
1441 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1444 /* =============================================================
1445 * State enable/disable
1448 static void radeonEnable( struct gl_context
*ctx
, GLenum cap
, GLboolean state
)
1450 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1453 if ( RADEON_DEBUG
& RADEON_STATE
)
1454 fprintf( stderr
, "%s( %s = %s )\n", __func__
,
1455 _mesa_enum_to_string( cap
),
1456 state
? "GL_TRUE" : "GL_FALSE" );
1459 /* Fast track this one...
1467 RADEON_STATECHANGE( rmesa
, ctx
);
1469 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1471 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1476 RADEON_STATECHANGE( rmesa
, ctx
);
1478 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1480 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1482 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1483 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1484 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1486 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1489 /* Catch a possible fallback:
1492 ctx
->Driver
.BlendEquationSeparate( ctx
,
1493 ctx
->Color
.Blend
[0].EquationRGB
,
1494 ctx
->Color
.Blend
[0].EquationA
);
1495 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.Blend
[0].SrcRGB
,
1496 ctx
->Color
.Blend
[0].DstRGB
,
1497 ctx
->Color
.Blend
[0].SrcA
,
1498 ctx
->Color
.Blend
[0].DstA
);
1501 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1502 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1506 case GL_CLIP_PLANE0
:
1507 case GL_CLIP_PLANE1
:
1508 case GL_CLIP_PLANE2
:
1509 case GL_CLIP_PLANE3
:
1510 case GL_CLIP_PLANE4
:
1511 case GL_CLIP_PLANE5
:
1512 p
= cap
-GL_CLIP_PLANE0
;
1513 RADEON_STATECHANGE( rmesa
, tcl
);
1515 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1516 radeonClipPlane( ctx
, cap
, NULL
);
1519 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1523 case GL_COLOR_MATERIAL
:
1524 radeonColorMaterial( ctx
, 0, 0 );
1525 radeonUpdateMaterial( ctx
);
1529 radeonCullFace( ctx
, 0 );
1533 RADEON_STATECHANGE(rmesa
, ctx
);
1535 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1537 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1542 RADEON_STATECHANGE(rmesa
, ctx
);
1544 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1545 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->radeon
.state
.color
.roundEnable
;
1547 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1548 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->radeon
.state
.color
.roundEnable
;
1553 RADEON_STATECHANGE(rmesa
, ctx
);
1555 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1556 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1558 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1559 RADEON_STATECHANGE(rmesa
, tcl
);
1560 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1562 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1563 _mesa_allow_light_in_model( ctx
, !state
);
1574 RADEON_STATECHANGE(rmesa
, tcl
);
1575 p
= cap
- GL_LIGHT0
;
1577 flag
= (RADEON_LIGHT_1_ENABLE
|
1578 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1579 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1581 flag
= (RADEON_LIGHT_0_ENABLE
|
1582 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1583 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1586 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1588 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1592 update_light_colors( ctx
, p
);
1596 RADEON_STATECHANGE(rmesa
, tcl
);
1597 radeonUpdateSpecular(ctx
);
1598 check_twoside_fallback( ctx
);
1601 case GL_LINE_SMOOTH
:
1602 RADEON_STATECHANGE( rmesa
, ctx
);
1604 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1606 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1610 case GL_LINE_STIPPLE
:
1611 RADEON_STATECHANGE( rmesa
, ctx
);
1613 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1615 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1619 case GL_COLOR_LOGIC_OP
:
1620 RADEON_STATECHANGE( rmesa
, ctx
);
1621 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1622 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1623 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1625 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1630 RADEON_STATECHANGE( rmesa
, tcl
);
1632 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1634 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1638 case GL_POLYGON_OFFSET_POINT
:
1639 RADEON_STATECHANGE( rmesa
, set
);
1641 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1643 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1647 case GL_POLYGON_OFFSET_LINE
:
1648 RADEON_STATECHANGE( rmesa
, set
);
1650 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1652 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1656 case GL_POLYGON_OFFSET_FILL
:
1657 RADEON_STATECHANGE( rmesa
, set
);
1659 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1661 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1665 case GL_POLYGON_SMOOTH
:
1666 RADEON_STATECHANGE( rmesa
, ctx
);
1668 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1670 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1674 case GL_POLYGON_STIPPLE
:
1675 RADEON_STATECHANGE(rmesa
, ctx
);
1677 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1679 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1683 case GL_RESCALE_NORMAL_EXT
: {
1684 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1685 RADEON_STATECHANGE( rmesa
, tcl
);
1687 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1689 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1694 case GL_SCISSOR_TEST
:
1695 radeon_firevertices(&rmesa
->radeon
);
1696 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1697 radeonUpdateScissor( ctx
);
1700 case GL_STENCIL_TEST
:
1702 GLboolean hw_stencil
= GL_FALSE
;
1703 if (ctx
->DrawBuffer
) {
1704 struct radeon_renderbuffer
*rrbStencil
1705 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
1706 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
1710 RADEON_STATECHANGE( rmesa
, ctx
);
1712 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1714 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1717 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1722 case GL_TEXTURE_GEN_Q
:
1723 case GL_TEXTURE_GEN_R
:
1724 case GL_TEXTURE_GEN_S
:
1725 case GL_TEXTURE_GEN_T
:
1726 /* Picked up in radeonUpdateTextureState.
1728 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1731 case GL_COLOR_SUM_EXT
:
1732 radeonUpdateSpecular ( ctx
);
1741 static void radeonLightingSpaceChange( struct gl_context
*ctx
)
1743 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1745 RADEON_STATECHANGE( rmesa
, tcl
);
1747 if (RADEON_DEBUG
& RADEON_STATE
)
1748 fprintf(stderr
, "%s %d BEFORE %x\n", __func__
, ctx
->_NeedEyeCoords
,
1749 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1751 if (ctx
->_NeedEyeCoords
)
1752 tmp
= ctx
->Transform
.RescaleNormals
;
1754 tmp
= !ctx
->Transform
.RescaleNormals
;
1757 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1759 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1762 if (RADEON_DEBUG
& RADEON_STATE
)
1763 fprintf(stderr
, "%s %d AFTER %x\n", __func__
, ctx
->_NeedEyeCoords
,
1764 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1767 /* =============================================================
1768 * Deferred state management - matrices, textures, other?
1772 void radeonUploadTexMatrix( r100ContextPtr rmesa
,
1773 int unit
, GLboolean swapcols
)
1775 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1776 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1777 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1778 texgen generates all 4 coords, at least tests with projtex indicated that.
1779 So: if we need the q coord in the end (solely determined by the texture
1780 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1781 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1782 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1783 will get submitted in the "wrong", i.e. 3rd, slot.
1784 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1785 size and using the texture matrix to swap the r and q coords around (ut2k3
1786 does exactly that), so we don't need the 3rd / 4th column swap - still need
1787 the 3rd / 4th row swap of course. This will potentially break for apps which
1788 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1789 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1790 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1791 incredibly hard to detect so we can't just fallback in such a case. Assume
1792 it never happens... - rs
1795 int idx
= TEXMAT_0
+ unit
;
1796 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
1798 struct gl_texture_unit tUnit
= rmesa
->radeon
.glCtx
.Texture
.Unit
[unit
];
1799 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
1801 rmesa
->TexMatColSwap
&= ~(1 << unit
);
1802 if (!tUnit
._Current
||
1803 (tUnit
._Current
->Target
!= GL_TEXTURE_3D
&&
1804 tUnit
._Current
->Target
!= GL_TEXTURE_CUBE_MAP
)) {
1806 rmesa
->TexMatColSwap
|= 1 << unit
;
1807 /* attention some elems are swapped 2 times! */
1820 /* those last 4 are probably never used */
1827 for (i
= 0; i
< 2; i
++) {
1831 *dest
++ = src
[i
+12];
1833 for (i
= 3; i
>= 2; i
--) {
1837 *dest
++ = src
[i
+12];
1842 for (i
= 0 ; i
< 4 ; i
++) {
1846 *dest
++ = src
[i
+12];
1850 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1854 static void upload_matrix( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1856 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1860 for (i
= 0 ; i
< 4 ; i
++) {
1864 *dest
++ = src
[i
+12];
1867 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1870 static void upload_matrix_t( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1872 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1873 memcpy(dest
, src
, 16*sizeof(float));
1874 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1878 static void update_texturematrix( struct gl_context
*ctx
)
1880 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
1881 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
1882 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
1884 GLuint texMatEnabled
= 0;
1885 rmesa
->NeedTexMatrix
= 0;
1886 rmesa
->TexMatColSwap
= 0;
1888 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
1889 if (ctx
->Texture
.Unit
[unit
]._Current
) {
1890 GLboolean needMatrix
= GL_FALSE
;
1891 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
1892 needMatrix
= GL_TRUE
;
1893 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
1894 RADEON_TEXMAT_0_ENABLE
) << unit
;
1896 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1897 /* Need to preconcatenate any active texgen
1898 * obj/eyeplane matrices:
1900 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
1901 ctx
->TextureMatrixStack
[unit
].Top
,
1902 &rmesa
->TexGenMatrix
[unit
] );
1905 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
1906 ctx
->TextureMatrixStack
[unit
].Top
);
1909 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1910 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
1911 needMatrix
= GL_TRUE
;
1914 rmesa
->NeedTexMatrix
|= 1 << unit
;
1915 radeonUploadTexMatrix( rmesa
, unit
,
1916 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
1921 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
1923 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1924 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
1925 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
1926 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
1928 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
1929 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
1930 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
1931 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
1932 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
1933 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
1935 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
1936 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
1938 RADEON_STATECHANGE(rmesa
, tcl
);
1939 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
1940 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
1944 GLboolean
r100ValidateBuffers(struct gl_context
*ctx
)
1946 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1947 struct radeon_renderbuffer
*rrb
;
1950 radeon_cs_space_reset_bos(rmesa
->radeon
.cmdbuf
.cs
);
1952 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
1954 if (rrb
&& rrb
->bo
) {
1955 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
1956 0, RADEON_GEM_DOMAIN_VRAM
);
1960 rrb
= radeon_get_depthbuffer(&rmesa
->radeon
);
1962 if (rrb
&& rrb
->bo
) {
1963 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
1964 0, RADEON_GEM_DOMAIN_VRAM
);
1967 for (i
= 0; i
< ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
; ++i
) {
1970 if (!ctx
->Texture
.Unit
[i
]._Current
)
1973 t
= rmesa
->state
.texture
.unit
[i
].texobj
;
1977 if (t
->image_override
&& t
->bo
)
1978 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->bo
,
1979 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
1981 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->mt
->bo
,
1982 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
1985 ret
= radeon_cs_space_check_with_bo(rmesa
->radeon
.cmdbuf
.cs
, first_elem(&rmesa
->radeon
.dma
.reserved
)->bo
, RADEON_GEM_DOMAIN_GTT
, 0);
1991 GLboolean
radeonValidateState( struct gl_context
*ctx
)
1993 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1994 GLuint new_state
= rmesa
->radeon
.NewGLState
;
1996 if (new_state
& _NEW_BUFFERS
) {
1997 _mesa_update_framebuffer(ctx
, ctx
->ReadBuffer
, ctx
->DrawBuffer
);
1998 /* this updates the DrawBuffer's Width/Height if it's a FBO */
1999 _mesa_update_draw_buffer_bounds(ctx
, ctx
->DrawBuffer
);
2000 RADEON_STATECHANGE(rmesa
, ctx
);
2003 if (new_state
& _NEW_TEXTURE
) {
2004 radeonUpdateTextureState( ctx
);
2005 new_state
|= rmesa
->radeon
.NewGLState
; /* may add TEXTURE_MATRIX */
2008 /* we need to do a space check here */
2009 if (!r100ValidateBuffers(ctx
))
2012 /* Need an event driven matrix update?
2014 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2015 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2017 /* Need these for lighting (shouldn't upload otherwise)
2019 if (new_state
& (_NEW_MODELVIEW
)) {
2020 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2021 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2024 /* Does this need to be triggered on eg. modelview for
2025 * texgen-derived objplane/eyeplane matrices?
2027 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2028 update_texturematrix( ctx
);
2031 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2032 update_light( ctx
);
2035 /* emit all active clip planes if projection matrix changes.
2037 if (new_state
& (_NEW_PROJECTION
)) {
2038 if (ctx
->Transform
.ClipPlanesEnabled
)
2039 radeonUpdateClipPlanes( ctx
);
2043 rmesa
->radeon
.NewGLState
= 0;
2049 static void radeonInvalidateState( struct gl_context
*ctx
, GLuint new_state
)
2051 _swrast_InvalidateState( ctx
, new_state
);
2052 _swsetup_InvalidateState( ctx
, new_state
);
2053 _vbo_InvalidateState( ctx
, new_state
);
2054 _tnl_InvalidateState( ctx
, new_state
);
2055 _ae_invalidate_state( ctx
, new_state
);
2056 R100_CONTEXT(ctx
)->radeon
.NewGLState
|= new_state
;
2060 /* A hack. Need a faster way to find this out.
2062 static GLboolean
check_material( struct gl_context
*ctx
)
2064 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2067 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2068 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2070 if (tnl
->vb
.AttribPtr
[i
] &&
2071 tnl
->vb
.AttribPtr
[i
]->stride
)
2078 static void radeonWrapRunPipeline( struct gl_context
*ctx
)
2080 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2081 GLboolean has_material
;
2084 fprintf(stderr
, "%s, newstate: %x\n", __func__
, rmesa
->radeon
.NewGLState
);
2088 if (rmesa
->radeon
.NewGLState
)
2089 if (!radeonValidateState( ctx
))
2090 FALLBACK(rmesa
, RADEON_FALLBACK_TEXTURE
, GL_TRUE
);
2092 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2095 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2098 /* Run the pipeline.
2100 _tnl_run_pipeline( ctx
);
2103 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2107 static void radeonPolygonStipple( struct gl_context
*ctx
, const GLubyte
*mask
)
2109 r100ContextPtr r100
= R100_CONTEXT(ctx
);
2112 radeon_firevertices(&r100
->radeon
);
2114 RADEON_STATECHANGE(r100
, stp
);
2116 /* Must flip pattern upside down.
2118 for ( i
= 31 ; i
>= 0; i
--) {
2119 r100
->hw
.stp
.cmd
[3 + i
] = ((GLuint
*) mask
)[i
];
2124 /* Initialize the driver's state functions.
2125 * Many of the ctx->Driver functions might have been initialized to
2126 * software defaults in the earlier _mesa_init_driver_functions() call.
2128 void radeonInitStateFuncs( struct gl_context
*ctx
)
2130 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2131 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2133 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2134 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2135 ctx
->Driver
.CopyPixels
= _mesa_meta_CopyPixels
;
2136 ctx
->Driver
.DrawPixels
= _mesa_meta_DrawPixels
;
2137 ctx
->Driver
.ReadPixels
= radeonReadPixels
;
2139 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2140 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2141 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2142 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2143 ctx
->Driver
.ColorMask
= radeonColorMask
;
2144 ctx
->Driver
.CullFace
= radeonCullFace
;
2145 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2146 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2147 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2148 ctx
->Driver
.Enable
= radeonEnable
;
2149 ctx
->Driver
.Fogfv
= radeonFogfv
;
2150 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2151 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2152 ctx
->Driver
.Lightfv
= radeonLightfv
;
2153 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2154 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2155 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2156 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2157 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2158 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2159 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2160 ctx
->Driver
.Scissor
= radeonScissor
;
2161 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2162 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2163 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2164 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2165 ctx
->Driver
.Viewport
= radeonViewport
;
2167 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2168 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;