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
);
1137 GLbitfield mask
= ctx
->Transform
.ClipPlanesEnabled
;
1140 const int p
= u_bit_scan(&mask
);
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];
1152 /* =============================================================
1157 radeonStencilFuncSeparate( struct gl_context
*ctx
, GLenum face
, GLenum func
,
1158 GLint ref
, GLuint mask
)
1160 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1161 GLuint refmask
= ((_mesa_get_stencil_ref(ctx
, 0) << RADEON_STENCIL_REF_SHIFT
) |
1162 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1164 RADEON_STATECHANGE( rmesa
, ctx
);
1165 RADEON_STATECHANGE( rmesa
, msk
);
1167 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1168 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1169 RADEON_STENCIL_VALUE_MASK
);
1171 switch ( ctx
->Stencil
.Function
[0] ) {
1173 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1176 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1179 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1182 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1185 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1188 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1191 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1194 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1198 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1202 radeonStencilMaskSeparate( struct gl_context
*ctx
, GLenum face
, GLuint mask
)
1204 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1206 RADEON_STATECHANGE( rmesa
, msk
);
1207 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1208 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1209 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1212 static void radeonStencilOpSeparate( struct gl_context
*ctx
, GLenum face
, GLenum fail
,
1213 GLenum zfail
, GLenum zpass
)
1215 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1217 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1218 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1219 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1221 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1222 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1223 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1224 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1225 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1226 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1228 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1229 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1230 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1231 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1232 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1233 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1234 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1237 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1238 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1239 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1240 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1241 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1242 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1245 RADEON_STATECHANGE( rmesa
, ctx
);
1246 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1247 RADEON_STENCIL_ZFAIL_MASK
|
1248 RADEON_STENCIL_ZPASS_MASK
);
1250 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1252 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1255 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1258 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1261 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1264 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1267 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1270 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1277 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1291 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1294 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1297 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1300 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1304 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1306 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1309 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1312 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1315 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1318 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1321 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1324 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1327 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1334 /* =============================================================
1335 * Window position and viewport transformation
1339 * To correctly position primitives:
1341 #define SUBPIXEL_X 0.125
1342 #define SUBPIXEL_Y 0.125
1346 * Called when window size or position changes or viewport or depth range
1347 * state is changed. We update the hardware viewport state here.
1349 void radeonUpdateWindow( struct gl_context
*ctx
)
1351 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1352 __DRIdrawable
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1353 GLfloat xoffset
= 0.0;
1354 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->h
: 0;
1355 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
? _mesa_is_user_fbo(ctx
->DrawBuffer
) : 0);
1356 float scale
[3], translate
[3];
1357 GLfloat y_scale
, y_bias
;
1359 if (render_to_fbo
) {
1367 _mesa_get_viewport_xform(ctx
, 0, scale
, translate
);
1368 float_ui32_type sx
= { scale
[0] };
1369 float_ui32_type sy
= { scale
[1] * y_scale
};
1370 float_ui32_type sz
= { scale
[2] };
1371 float_ui32_type tx
= { translate
[0] + xoffset
+ SUBPIXEL_X
};
1372 float_ui32_type ty
= { (translate
[1] * y_scale
) + y_bias
+ SUBPIXEL_Y
};
1373 float_ui32_type tz
= { translate
[2] };
1375 RADEON_STATECHANGE( rmesa
, vpt
);
1377 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1378 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1379 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1380 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1381 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1382 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1386 static void radeonViewport(struct gl_context
*ctx
)
1388 /* Don't pipeline viewport changes, conflict with window offset
1389 * setting below. Could apply deltas to rescue pipelined viewport
1390 * values, or keep the originals hanging around.
1392 radeonUpdateWindow( ctx
);
1394 radeon_viewport(ctx
);
1397 static void radeonDepthRange(struct gl_context
*ctx
)
1399 radeonUpdateWindow( ctx
);
1402 /* =============================================================
1406 static void radeonRenderMode( struct gl_context
*ctx
, GLenum mode
)
1408 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1409 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1413 static GLuint radeon_rop_tab
[] = {
1416 RADEON_ROP_AND_REVERSE
,
1418 RADEON_ROP_AND_INVERTED
,
1425 RADEON_ROP_OR_REVERSE
,
1426 RADEON_ROP_COPY_INVERTED
,
1427 RADEON_ROP_OR_INVERTED
,
1432 static void radeonLogicOpCode( struct gl_context
*ctx
, GLenum opcode
)
1434 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1435 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1439 RADEON_STATECHANGE( rmesa
, msk
);
1440 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1443 /* =============================================================
1444 * State enable/disable
1447 static void radeonEnable( struct gl_context
*ctx
, GLenum cap
, GLboolean state
)
1449 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1452 if ( RADEON_DEBUG
& RADEON_STATE
)
1453 fprintf( stderr
, "%s( %s = %s )\n", __func__
,
1454 _mesa_enum_to_string( cap
),
1455 state
? "GL_TRUE" : "GL_FALSE" );
1458 /* Fast track this one...
1466 RADEON_STATECHANGE( rmesa
, ctx
);
1468 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1470 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1475 RADEON_STATECHANGE( rmesa
, ctx
);
1477 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1479 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1481 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1482 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1483 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1485 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1488 /* Catch a possible fallback:
1491 ctx
->Driver
.BlendEquationSeparate( ctx
,
1492 ctx
->Color
.Blend
[0].EquationRGB
,
1493 ctx
->Color
.Blend
[0].EquationA
);
1494 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.Blend
[0].SrcRGB
,
1495 ctx
->Color
.Blend
[0].DstRGB
,
1496 ctx
->Color
.Blend
[0].SrcA
,
1497 ctx
->Color
.Blend
[0].DstA
);
1500 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1501 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1505 case GL_CLIP_PLANE0
:
1506 case GL_CLIP_PLANE1
:
1507 case GL_CLIP_PLANE2
:
1508 case GL_CLIP_PLANE3
:
1509 case GL_CLIP_PLANE4
:
1510 case GL_CLIP_PLANE5
:
1511 p
= cap
-GL_CLIP_PLANE0
;
1512 RADEON_STATECHANGE( rmesa
, tcl
);
1514 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1515 radeonClipPlane( ctx
, cap
, NULL
);
1518 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1522 case GL_COLOR_MATERIAL
:
1523 radeonColorMaterial( ctx
, 0, 0 );
1524 radeonUpdateMaterial( ctx
);
1528 radeonCullFace( ctx
, 0 );
1532 RADEON_STATECHANGE(rmesa
, ctx
);
1534 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1536 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1541 RADEON_STATECHANGE(rmesa
, ctx
);
1543 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1544 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->radeon
.state
.color
.roundEnable
;
1546 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1547 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->radeon
.state
.color
.roundEnable
;
1552 RADEON_STATECHANGE(rmesa
, ctx
);
1554 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1555 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1557 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1558 RADEON_STATECHANGE(rmesa
, tcl
);
1559 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1561 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1562 _mesa_allow_light_in_model( ctx
, !state
);
1573 RADEON_STATECHANGE(rmesa
, tcl
);
1574 p
= cap
- GL_LIGHT0
;
1576 flag
= (RADEON_LIGHT_1_ENABLE
|
1577 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1578 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1580 flag
= (RADEON_LIGHT_0_ENABLE
|
1581 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1582 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1585 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1587 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1591 update_light_colors( ctx
, p
);
1595 RADEON_STATECHANGE(rmesa
, tcl
);
1596 radeonUpdateSpecular(ctx
);
1597 check_twoside_fallback( ctx
);
1600 case GL_LINE_SMOOTH
:
1601 RADEON_STATECHANGE( rmesa
, ctx
);
1603 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1605 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1609 case GL_LINE_STIPPLE
:
1610 RADEON_STATECHANGE( rmesa
, ctx
);
1612 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1614 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1618 case GL_COLOR_LOGIC_OP
:
1619 RADEON_STATECHANGE( rmesa
, ctx
);
1620 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1621 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1622 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1624 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1629 RADEON_STATECHANGE( rmesa
, tcl
);
1631 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1633 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1637 case GL_POLYGON_OFFSET_POINT
:
1638 RADEON_STATECHANGE( rmesa
, set
);
1640 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1642 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1646 case GL_POLYGON_OFFSET_LINE
:
1647 RADEON_STATECHANGE( rmesa
, set
);
1649 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1651 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1655 case GL_POLYGON_OFFSET_FILL
:
1656 RADEON_STATECHANGE( rmesa
, set
);
1658 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1660 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1664 case GL_POLYGON_SMOOTH
:
1665 RADEON_STATECHANGE( rmesa
, ctx
);
1667 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1669 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1673 case GL_POLYGON_STIPPLE
:
1674 RADEON_STATECHANGE(rmesa
, ctx
);
1676 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1678 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1682 case GL_RESCALE_NORMAL_EXT
: {
1683 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1684 RADEON_STATECHANGE( rmesa
, tcl
);
1686 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1688 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1693 case GL_SCISSOR_TEST
:
1694 radeon_firevertices(&rmesa
->radeon
);
1695 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1696 radeonUpdateScissor( ctx
);
1699 case GL_STENCIL_TEST
:
1701 GLboolean hw_stencil
= GL_FALSE
;
1702 if (ctx
->DrawBuffer
) {
1703 struct radeon_renderbuffer
*rrbStencil
1704 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
1705 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
1709 RADEON_STATECHANGE( rmesa
, ctx
);
1711 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1713 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1716 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1721 case GL_TEXTURE_GEN_Q
:
1722 case GL_TEXTURE_GEN_R
:
1723 case GL_TEXTURE_GEN_S
:
1724 case GL_TEXTURE_GEN_T
:
1725 /* Picked up in radeonUpdateTextureState.
1727 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1730 case GL_COLOR_SUM_EXT
:
1731 radeonUpdateSpecular ( ctx
);
1740 static void radeonLightingSpaceChange( struct gl_context
*ctx
)
1742 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1744 RADEON_STATECHANGE( rmesa
, tcl
);
1746 if (RADEON_DEBUG
& RADEON_STATE
)
1747 fprintf(stderr
, "%s %d BEFORE %x\n", __func__
, ctx
->_NeedEyeCoords
,
1748 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1750 if (ctx
->_NeedEyeCoords
)
1751 tmp
= ctx
->Transform
.RescaleNormals
;
1753 tmp
= !ctx
->Transform
.RescaleNormals
;
1756 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1758 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1761 if (RADEON_DEBUG
& RADEON_STATE
)
1762 fprintf(stderr
, "%s %d AFTER %x\n", __func__
, ctx
->_NeedEyeCoords
,
1763 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1766 /* =============================================================
1767 * Deferred state management - matrices, textures, other?
1771 void radeonUploadTexMatrix( r100ContextPtr rmesa
,
1772 int unit
, GLboolean swapcols
)
1774 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1775 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1776 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1777 texgen generates all 4 coords, at least tests with projtex indicated that.
1778 So: if we need the q coord in the end (solely determined by the texture
1779 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1780 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1781 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1782 will get submitted in the "wrong", i.e. 3rd, slot.
1783 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1784 size and using the texture matrix to swap the r and q coords around (ut2k3
1785 does exactly that), so we don't need the 3rd / 4th column swap - still need
1786 the 3rd / 4th row swap of course. This will potentially break for apps which
1787 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1788 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1789 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1790 incredibly hard to detect so we can't just fallback in such a case. Assume
1791 it never happens... - rs
1794 int idx
= TEXMAT_0
+ unit
;
1795 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
1797 struct gl_texture_unit tUnit
= rmesa
->radeon
.glCtx
.Texture
.Unit
[unit
];
1798 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
1800 rmesa
->TexMatColSwap
&= ~(1 << unit
);
1801 if (!tUnit
._Current
||
1802 (tUnit
._Current
->Target
!= GL_TEXTURE_3D
&&
1803 tUnit
._Current
->Target
!= GL_TEXTURE_CUBE_MAP
)) {
1805 rmesa
->TexMatColSwap
|= 1 << unit
;
1806 /* attention some elems are swapped 2 times! */
1819 /* those last 4 are probably never used */
1826 for (i
= 0; i
< 2; i
++) {
1830 *dest
++ = src
[i
+12];
1832 for (i
= 3; i
>= 2; i
--) {
1836 *dest
++ = src
[i
+12];
1841 for (i
= 0 ; i
< 4 ; i
++) {
1845 *dest
++ = src
[i
+12];
1849 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1853 static void upload_matrix( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1855 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1859 for (i
= 0 ; i
< 4 ; i
++) {
1863 *dest
++ = src
[i
+12];
1866 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1869 static void upload_matrix_t( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1871 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1872 memcpy(dest
, src
, 16*sizeof(float));
1873 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1877 static void update_texturematrix( struct gl_context
*ctx
)
1879 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
1880 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
1881 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
1883 GLuint texMatEnabled
= 0;
1884 rmesa
->NeedTexMatrix
= 0;
1885 rmesa
->TexMatColSwap
= 0;
1887 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
1888 if (ctx
->Texture
.Unit
[unit
]._Current
) {
1889 GLboolean needMatrix
= GL_FALSE
;
1890 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
1891 needMatrix
= GL_TRUE
;
1892 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
1893 RADEON_TEXMAT_0_ENABLE
) << unit
;
1895 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1896 /* Need to preconcatenate any active texgen
1897 * obj/eyeplane matrices:
1899 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
1900 ctx
->TextureMatrixStack
[unit
].Top
,
1901 &rmesa
->TexGenMatrix
[unit
] );
1904 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
1905 ctx
->TextureMatrixStack
[unit
].Top
);
1908 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1909 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
1910 needMatrix
= GL_TRUE
;
1913 rmesa
->NeedTexMatrix
|= 1 << unit
;
1914 radeonUploadTexMatrix( rmesa
, unit
,
1915 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
1920 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
1922 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1923 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
1924 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
1925 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
1927 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
1928 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
1929 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
1930 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
1931 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
1932 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
1934 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
1935 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
1937 RADEON_STATECHANGE(rmesa
, tcl
);
1938 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
1939 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
1943 GLboolean
r100ValidateBuffers(struct gl_context
*ctx
)
1945 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1946 struct radeon_renderbuffer
*rrb
;
1949 radeon_cs_space_reset_bos(rmesa
->radeon
.cmdbuf
.cs
);
1951 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
1953 if (rrb
&& rrb
->bo
) {
1954 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
1955 0, RADEON_GEM_DOMAIN_VRAM
);
1959 rrb
= radeon_get_depthbuffer(&rmesa
->radeon
);
1961 if (rrb
&& rrb
->bo
) {
1962 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
1963 0, RADEON_GEM_DOMAIN_VRAM
);
1966 for (i
= 0; i
< ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
; ++i
) {
1969 if (!ctx
->Texture
.Unit
[i
]._Current
)
1972 t
= rmesa
->state
.texture
.unit
[i
].texobj
;
1976 if (t
->image_override
&& t
->bo
)
1977 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->bo
,
1978 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
1980 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->mt
->bo
,
1981 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
1984 ret
= radeon_cs_space_check_with_bo(rmesa
->radeon
.cmdbuf
.cs
, first_elem(&rmesa
->radeon
.dma
.reserved
)->bo
, RADEON_GEM_DOMAIN_GTT
, 0);
1990 GLboolean
radeonValidateState( struct gl_context
*ctx
)
1992 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1993 GLuint new_state
= rmesa
->radeon
.NewGLState
;
1995 if (new_state
& _NEW_BUFFERS
) {
1996 _mesa_update_framebuffer(ctx
, ctx
->ReadBuffer
, ctx
->DrawBuffer
);
1997 /* this updates the DrawBuffer's Width/Height if it's a FBO */
1998 _mesa_update_draw_buffer_bounds(ctx
, ctx
->DrawBuffer
);
1999 RADEON_STATECHANGE(rmesa
, ctx
);
2002 if (new_state
& _NEW_TEXTURE
) {
2003 radeonUpdateTextureState( ctx
);
2004 new_state
|= rmesa
->radeon
.NewGLState
; /* may add TEXTURE_MATRIX */
2007 /* we need to do a space check here */
2008 if (!r100ValidateBuffers(ctx
))
2011 /* Need an event driven matrix update?
2013 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2014 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2016 /* Need these for lighting (shouldn't upload otherwise)
2018 if (new_state
& (_NEW_MODELVIEW
)) {
2019 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2020 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2023 /* Does this need to be triggered on eg. modelview for
2024 * texgen-derived objplane/eyeplane matrices?
2026 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2027 update_texturematrix( ctx
);
2030 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2031 update_light( ctx
);
2034 /* emit all active clip planes if projection matrix changes.
2036 if (new_state
& (_NEW_PROJECTION
)) {
2037 if (ctx
->Transform
.ClipPlanesEnabled
)
2038 radeonUpdateClipPlanes( ctx
);
2042 rmesa
->radeon
.NewGLState
= 0;
2048 static void radeonInvalidateState( struct gl_context
*ctx
, GLuint new_state
)
2050 _swrast_InvalidateState( ctx
, new_state
);
2051 _swsetup_InvalidateState( ctx
, new_state
);
2052 _vbo_InvalidateState( ctx
, new_state
);
2053 _tnl_InvalidateState( ctx
, new_state
);
2054 _ae_invalidate_state( ctx
, new_state
);
2055 R100_CONTEXT(ctx
)->radeon
.NewGLState
|= new_state
;
2059 /* A hack. Need a faster way to find this out.
2061 static GLboolean
check_material( struct gl_context
*ctx
)
2063 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2066 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2067 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2069 if (tnl
->vb
.AttribPtr
[i
] &&
2070 tnl
->vb
.AttribPtr
[i
]->stride
)
2077 static void radeonWrapRunPipeline( struct gl_context
*ctx
)
2079 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2080 GLboolean has_material
;
2083 fprintf(stderr
, "%s, newstate: %x\n", __func__
, rmesa
->radeon
.NewGLState
);
2087 if (rmesa
->radeon
.NewGLState
)
2088 if (!radeonValidateState( ctx
))
2089 FALLBACK(rmesa
, RADEON_FALLBACK_TEXTURE
, GL_TRUE
);
2091 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2094 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2097 /* Run the pipeline.
2099 _tnl_run_pipeline( ctx
);
2102 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2106 static void radeonPolygonStipple( struct gl_context
*ctx
, const GLubyte
*mask
)
2108 r100ContextPtr r100
= R100_CONTEXT(ctx
);
2111 radeon_firevertices(&r100
->radeon
);
2113 RADEON_STATECHANGE(r100
, stp
);
2115 /* Must flip pattern upside down.
2117 for ( i
= 31 ; i
>= 0; i
--) {
2118 r100
->hw
.stp
.cmd
[3 + i
] = ((GLuint
*) mask
)[i
];
2123 /* Initialize the driver's state functions.
2124 * Many of the ctx->Driver functions might have been initialized to
2125 * software defaults in the earlier _mesa_init_driver_functions() call.
2127 void radeonInitStateFuncs( struct gl_context
*ctx
)
2129 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2130 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2132 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2133 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2134 ctx
->Driver
.CopyPixels
= _mesa_meta_CopyPixels
;
2135 ctx
->Driver
.DrawPixels
= _mesa_meta_DrawPixels
;
2136 ctx
->Driver
.ReadPixels
= radeonReadPixels
;
2138 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2139 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2140 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2141 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2142 ctx
->Driver
.ColorMask
= radeonColorMask
;
2143 ctx
->Driver
.CullFace
= radeonCullFace
;
2144 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2145 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2146 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2147 ctx
->Driver
.Enable
= radeonEnable
;
2148 ctx
->Driver
.Fogfv
= radeonFogfv
;
2149 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2150 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2151 ctx
->Driver
.Lightfv
= radeonLightfv
;
2152 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2153 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2154 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2155 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2156 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2157 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2158 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2159 ctx
->Driver
.Scissor
= radeonScissor
;
2160 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2161 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2162 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2163 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2164 ctx
->Driver
.Viewport
= radeonViewport
;
2166 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2167 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;