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/enums.h"
38 #include "main/light.h"
39 #include "main/context.h"
40 #include "main/framebuffer.h"
41 #include "main/fbobject.h"
42 #include "util/simple_list.h"
43 #include "main/state.h"
44 #include "main/core.h"
45 #include "main/stencil.h"
46 #include "main/viewport.h"
50 #include "tnl/t_pipeline.h"
51 #include "swrast_setup/swrast_setup.h"
52 #include "drivers/common/meta.h"
53 #include "util/bitscan.h"
55 #include "radeon_context.h"
56 #include "radeon_mipmap_tree.h"
57 #include "radeon_ioctl.h"
58 #include "radeon_state.h"
59 #include "radeon_tcl.h"
60 #include "radeon_tex.h"
61 #include "radeon_swtcl.h"
63 static void radeonUpdateSpecular( struct gl_context
*ctx
);
65 /* =============================================================
69 static void radeonAlphaFunc( struct gl_context
*ctx
, GLenum func
, GLfloat ref
)
71 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
72 int pp_misc
= rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
];
75 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
77 RADEON_STATECHANGE( rmesa
, ctx
);
79 pp_misc
&= ~(RADEON_ALPHA_TEST_OP_MASK
| RADEON_REF_ALPHA_MASK
);
80 pp_misc
|= (refByte
& RADEON_REF_ALPHA_MASK
);
84 pp_misc
|= RADEON_ALPHA_TEST_FAIL
;
87 pp_misc
|= RADEON_ALPHA_TEST_LESS
;
90 pp_misc
|= RADEON_ALPHA_TEST_EQUAL
;
93 pp_misc
|= RADEON_ALPHA_TEST_LEQUAL
;
96 pp_misc
|= RADEON_ALPHA_TEST_GREATER
;
99 pp_misc
|= RADEON_ALPHA_TEST_NEQUAL
;
102 pp_misc
|= RADEON_ALPHA_TEST_GEQUAL
;
105 pp_misc
|= RADEON_ALPHA_TEST_PASS
;
109 rmesa
->hw
.ctx
.cmd
[CTX_PP_MISC
] = pp_misc
;
112 static void radeonBlendEquationSeparate( struct gl_context
*ctx
,
113 GLenum modeRGB
, GLenum modeA
)
115 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
116 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] & ~RADEON_COMB_FCN_MASK
;
117 GLboolean fallback
= GL_FALSE
;
119 assert( modeRGB
== modeA
);
124 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
127 case GL_FUNC_SUBTRACT
:
128 b
|= RADEON_COMB_FCN_SUB_CLAMP
;
132 if (ctx
->Color
.BlendEnabled
)
135 b
|= RADEON_COMB_FCN_ADD_CLAMP
;
139 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, fallback
);
141 RADEON_STATECHANGE( rmesa
, ctx
);
142 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
143 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
144 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
145 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
147 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
152 static void radeonBlendFuncSeparate( struct gl_context
*ctx
,
153 GLenum sfactorRGB
, GLenum dfactorRGB
,
154 GLenum sfactorA
, GLenum dfactorA
)
156 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
157 GLuint b
= rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] &
158 ~(RADEON_SRC_BLEND_MASK
| RADEON_DST_BLEND_MASK
);
159 GLboolean fallback
= GL_FALSE
;
161 switch ( ctx
->Color
.Blend
[0].SrcRGB
) {
163 b
|= RADEON_SRC_BLEND_GL_ZERO
;
166 b
|= RADEON_SRC_BLEND_GL_ONE
;
169 b
|= RADEON_SRC_BLEND_GL_DST_COLOR
;
171 case GL_ONE_MINUS_DST_COLOR
:
172 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR
;
175 b
|= RADEON_SRC_BLEND_GL_SRC_COLOR
;
177 case GL_ONE_MINUS_SRC_COLOR
:
178 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR
;
181 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA
;
183 case GL_ONE_MINUS_SRC_ALPHA
:
184 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
187 b
|= RADEON_SRC_BLEND_GL_DST_ALPHA
;
189 case GL_ONE_MINUS_DST_ALPHA
:
190 b
|= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA
;
192 case GL_SRC_ALPHA_SATURATE
:
193 b
|= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE
;
195 case GL_CONSTANT_COLOR
:
196 case GL_ONE_MINUS_CONSTANT_COLOR
:
197 case GL_CONSTANT_ALPHA
:
198 case GL_ONE_MINUS_CONSTANT_ALPHA
:
199 if (ctx
->Color
.BlendEnabled
)
202 b
|= RADEON_SRC_BLEND_GL_ONE
;
208 switch ( ctx
->Color
.Blend
[0].DstRGB
) {
210 b
|= RADEON_DST_BLEND_GL_ZERO
;
213 b
|= RADEON_DST_BLEND_GL_ONE
;
216 b
|= RADEON_DST_BLEND_GL_SRC_COLOR
;
218 case GL_ONE_MINUS_SRC_COLOR
:
219 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR
;
222 b
|= RADEON_DST_BLEND_GL_SRC_ALPHA
;
224 case GL_ONE_MINUS_SRC_ALPHA
:
225 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
228 b
|= RADEON_DST_BLEND_GL_DST_COLOR
;
230 case GL_ONE_MINUS_DST_COLOR
:
231 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR
;
234 b
|= RADEON_DST_BLEND_GL_DST_ALPHA
;
236 case GL_ONE_MINUS_DST_ALPHA
:
237 b
|= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA
;
239 case GL_CONSTANT_COLOR
:
240 case GL_ONE_MINUS_CONSTANT_COLOR
:
241 case GL_CONSTANT_ALPHA
:
242 case GL_ONE_MINUS_CONSTANT_ALPHA
:
243 if (ctx
->Color
.BlendEnabled
)
246 b
|= RADEON_DST_BLEND_GL_ZERO
;
252 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, fallback
);
254 RADEON_STATECHANGE( rmesa
, ctx
);
255 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_BLENDCNTL
] = b
;
260 /* =============================================================
264 static void radeonDepthFunc( struct gl_context
*ctx
, GLenum func
)
266 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
268 RADEON_STATECHANGE( rmesa
, ctx
);
269 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_TEST_MASK
;
271 switch ( ctx
->Depth
.Func
) {
273 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEVER
;
276 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LESS
;
279 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_EQUAL
;
282 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_LEQUAL
;
285 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GREATER
;
288 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_NEQUAL
;
291 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_GEQUAL
;
294 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_TEST_ALWAYS
;
300 static void radeonDepthMask( struct gl_context
*ctx
, GLboolean flag
)
302 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
303 RADEON_STATECHANGE( rmesa
, ctx
);
305 if ( ctx
->Depth
.Mask
) {
306 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_Z_WRITE_ENABLE
;
308 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_Z_WRITE_ENABLE
;
313 /* =============================================================
318 static void radeonFogfv( struct gl_context
*ctx
, GLenum pname
, const GLfloat
*param
)
320 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
321 union { int i
; float f
; } c
, d
;
326 if (!ctx
->Fog
.Enabled
)
328 RADEON_STATECHANGE(rmesa
, tcl
);
329 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
330 switch (ctx
->Fog
.Mode
) {
332 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_LINEAR
;
335 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP
;
338 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_TCL_FOG_EXP2
;
347 if (!ctx
->Fog
.Enabled
)
349 c
.i
= rmesa
->hw
.fog
.cmd
[FOG_C
];
350 d
.i
= rmesa
->hw
.fog
.cmd
[FOG_D
];
351 switch (ctx
->Fog
.Mode
) {
354 /* While this is the opposite sign from the DDK, it makes the fog test
355 * pass, and matches r200.
357 d
.f
= -ctx
->Fog
.Density
;
361 d
.f
= -(ctx
->Fog
.Density
* ctx
->Fog
.Density
);
364 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
368 c
.f
= ctx
->Fog
.End
/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
369 /* While this is the opposite sign from the DDK, it makes the fog
370 * test pass, and matches r200.
372 d
.f
= -1.0/(ctx
->Fog
.End
-ctx
->Fog
.Start
);
378 if (c
.i
!= rmesa
->hw
.fog
.cmd
[FOG_C
] || d
.i
!= rmesa
->hw
.fog
.cmd
[FOG_D
]) {
379 RADEON_STATECHANGE( rmesa
, fog
);
380 rmesa
->hw
.fog
.cmd
[FOG_C
] = c
.i
;
381 rmesa
->hw
.fog
.cmd
[FOG_D
] = d
.i
;
385 RADEON_STATECHANGE( rmesa
, ctx
);
386 _mesa_unclamped_float_rgba_to_ubyte(col
, ctx
->Fog
.Color
);
387 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] &= ~RADEON_FOG_COLOR_MASK
;
388 rmesa
->hw
.ctx
.cmd
[CTX_PP_FOG_COLOR
] |=
389 radeonPackColor( 4, col
[0], col
[1], col
[2], 0 );
391 case GL_FOG_COORD_SRC
:
392 radeonUpdateSpecular( ctx
);
399 /* =============================================================
403 static void radeonCullFace( struct gl_context
*ctx
, GLenum unused
)
405 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
406 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
407 GLuint t
= rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
];
409 s
|= RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
;
410 t
&= ~(RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
412 if ( ctx
->Polygon
.CullFlag
) {
413 switch ( ctx
->Polygon
.CullFaceMode
) {
415 s
&= ~RADEON_FFACE_SOLID
;
416 t
|= RADEON_CULL_FRONT
;
419 s
&= ~RADEON_BFACE_SOLID
;
420 t
|= RADEON_CULL_BACK
;
422 case GL_FRONT_AND_BACK
:
423 s
&= ~(RADEON_FFACE_SOLID
| RADEON_BFACE_SOLID
);
424 t
|= (RADEON_CULL_FRONT
| RADEON_CULL_BACK
);
429 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
430 RADEON_STATECHANGE(rmesa
, set
);
431 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
434 if ( rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] != t
) {
435 RADEON_STATECHANGE(rmesa
, tcl
);
436 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] = t
;
440 static void radeonFrontFace( struct gl_context
*ctx
, GLenum mode
)
442 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
443 int cull_face
= (mode
== GL_CW
) ? RADEON_FFACE_CULL_CW
: RADEON_FFACE_CULL_CCW
;
445 RADEON_STATECHANGE( rmesa
, set
);
446 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_FFACE_CULL_DIR_MASK
;
448 RADEON_STATECHANGE( rmesa
, tcl
);
449 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_CULL_FRONT_IS_CCW
;
451 /* Winding is inverted when rendering to FBO */
452 if (ctx
->DrawBuffer
&& _mesa_is_user_fbo(ctx
->DrawBuffer
))
453 cull_face
= (mode
== GL_CCW
) ? RADEON_FFACE_CULL_CW
: RADEON_FFACE_CULL_CCW
;
454 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= cull_face
;
456 if ( mode
== GL_CCW
)
457 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_CULL_FRONT_IS_CCW
;
461 /* =============================================================
464 static void radeonLineWidth( struct gl_context
*ctx
, GLfloat widthf
)
466 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
468 RADEON_STATECHANGE( rmesa
, lin
);
469 RADEON_STATECHANGE( rmesa
, set
);
471 /* Line width is stored in U6.4 format.
473 rmesa
->hw
.lin
.cmd
[LIN_SE_LINE_WIDTH
] = (GLuint
)(widthf
* 16.0);
474 if ( widthf
> 1.0 ) {
475 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_WIDELINE_ENABLE
;
477 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_WIDELINE_ENABLE
;
481 static void radeonLineStipple( struct gl_context
*ctx
, GLint factor
, GLushort pattern
)
483 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
485 RADEON_STATECHANGE( rmesa
, lin
);
486 rmesa
->hw
.lin
.cmd
[LIN_RE_LINE_PATTERN
] =
487 ((((GLuint
)factor
& 0xff) << 16) | ((GLuint
)pattern
));
491 /* =============================================================
494 static void radeonColorMask( struct gl_context
*ctx
,
495 GLboolean r
, GLboolean g
,
496 GLboolean b
, GLboolean a
)
498 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
499 struct radeon_renderbuffer
*rrb
;
502 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
506 mask
= radeonPackColor( rrb
->cpp
,
507 ctx
->Color
.ColorMask
[0][RCOMP
],
508 ctx
->Color
.ColorMask
[0][GCOMP
],
509 ctx
->Color
.ColorMask
[0][BCOMP
],
510 ctx
->Color
.ColorMask
[0][ACOMP
] );
512 if ( rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] != mask
) {
513 RADEON_STATECHANGE( rmesa
, msk
);
514 rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
] = mask
;
519 /* =============================================================
523 static void radeonPolygonOffset( struct gl_context
*ctx
,
524 GLfloat factor
, GLfloat units
, GLfloat clamp
)
526 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
527 const GLfloat depthScale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
528 float_ui32_type constant
= { units
* depthScale
};
529 float_ui32_type factoru
= { factor
};
531 RADEON_STATECHANGE( rmesa
, zbs
);
532 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_FACTOR
] = factoru
.ui32
;
533 rmesa
->hw
.zbs
.cmd
[ZBS_SE_ZBIAS_CONSTANT
] = constant
.ui32
;
536 static void radeonPolygonMode( struct gl_context
*ctx
, GLenum face
, GLenum mode
)
538 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
539 GLboolean unfilled
= (ctx
->Polygon
.FrontMode
!= GL_FILL
||
540 ctx
->Polygon
.BackMode
!= GL_FILL
);
542 /* Can't generally do unfilled via tcl, but some good special
545 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_UNFILLED
, unfilled
);
546 if (rmesa
->radeon
.TclFallback
) {
547 radeonChooseRenderState( ctx
);
548 radeonChooseVertexState( ctx
);
553 /* =============================================================
554 * Rendering attributes
556 * We really don't want to recalculate all this every time we bind a
557 * texture. These things shouldn't change all that often, so it makes
558 * sense to break them out of the core texture state update routines.
561 /* Examine lighting and texture state to determine if separate specular
564 static void radeonUpdateSpecular( struct gl_context
*ctx
)
566 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
567 uint32_t p
= rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
];
570 RADEON_STATECHANGE( rmesa
, tcl
);
572 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_SPECULAR
;
573 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &= ~RADEON_TCL_COMPUTE_DIFFUSE
;
574 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_SPEC
;
575 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~RADEON_TCL_VTX_PK_DIFFUSE
;
576 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LIGHTING_ENABLE
;
578 p
&= ~RADEON_SPECULAR_ENABLE
;
580 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_DIFFUSE_SPECULAR_COMBINE
;
583 if (ctx
->Light
.Enabled
&&
584 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
) {
585 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
586 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
587 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
588 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
589 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
590 p
|= RADEON_SPECULAR_ENABLE
;
591 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &=
592 ~RADEON_DIFFUSE_SPECULAR_COMBINE
;
594 else if (ctx
->Light
.Enabled
) {
595 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_DIFFUSE
;
596 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
597 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
598 } else if (ctx
->Fog
.ColorSumEnabled
) {
599 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
600 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
601 p
|= RADEON_SPECULAR_ENABLE
;
603 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_DIFFUSE
;
606 if (ctx
->Fog
.Enabled
) {
607 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_PK_SPEC
;
608 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH
) {
609 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] |= RADEON_TCL_COMPUTE_SPECULAR
;
610 /* Bizzare: have to leave lighting enabled to get fog. */
611 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LIGHTING_ENABLE
;
614 /* cannot do tcl fog factor calculation with fog coord source
615 * (send precomputed factors). Cannot use precomputed fog
616 * factors together with tcl spec light (need tcl fallback) */
617 flag
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] &
618 RADEON_TCL_COMPUTE_SPECULAR
) != 0;
622 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_FOGCOORDSPEC
, flag
);
624 if (_mesa_need_secondary_color(ctx
)) {
625 assert( (p
& RADEON_SPECULAR_ENABLE
) != 0 );
627 assert( (p
& RADEON_SPECULAR_ENABLE
) == 0 );
630 if ( rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] != p
) {
631 RADEON_STATECHANGE( rmesa
, ctx
);
632 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] = p
;
635 /* Update vertex/render formats
637 if (rmesa
->radeon
.TclFallback
) {
638 radeonChooseRenderState( ctx
);
639 radeonChooseVertexState( ctx
);
644 /* =============================================================
649 /* Update on colormaterial, material emmissive/ambient,
650 * lightmodel.globalambient
652 static void update_global_ambient( struct gl_context
*ctx
)
654 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
655 float *fcmd
= (float *)RADEON_DB_STATE( glt
);
657 /* Need to do more if both emmissive & ambient are PREMULT:
658 * Hope this is not needed for MULT
660 if ((rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &
661 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
662 (3 << RADEON_AMBIENT_SOURCE_SHIFT
))) == 0)
664 COPY_3V( &fcmd
[GLT_RED
],
665 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_EMISSION
]);
666 ACC_SCALE_3V( &fcmd
[GLT_RED
],
667 ctx
->Light
.Model
.Ambient
,
668 ctx
->Light
.Material
.Attrib
[MAT_ATTRIB_FRONT_AMBIENT
]);
672 COPY_3V( &fcmd
[GLT_RED
], ctx
->Light
.Model
.Ambient
);
675 RADEON_DB_STATECHANGE(rmesa
, &rmesa
->hw
.glt
);
678 /* Update on change to
682 static void update_light_colors( struct gl_context
*ctx
, GLuint p
)
684 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
686 /* fprintf(stderr, "%s\n", __func__); */
689 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
690 float *fcmd
= (float *)RADEON_DB_STATE( lit
[p
] );
692 COPY_4V( &fcmd
[LIT_AMBIENT_RED
], l
->Ambient
);
693 COPY_4V( &fcmd
[LIT_DIFFUSE_RED
], l
->Diffuse
);
694 COPY_4V( &fcmd
[LIT_SPECULAR_RED
], l
->Specular
);
696 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
700 /* Also fallback for asym colormaterial mode in twoside lighting...
702 static void check_twoside_fallback( struct gl_context
*ctx
)
704 GLboolean fallback
= GL_FALSE
;
707 if (ctx
->Light
.Enabled
&& ctx
->Light
.Model
.TwoSide
) {
708 if (ctx
->Light
.ColorMaterialEnabled
&&
709 (ctx
->Light
._ColorMaterialBitmask
& BACK_MATERIAL_BITS
) !=
710 ((ctx
->Light
._ColorMaterialBitmask
& FRONT_MATERIAL_BITS
)<<1))
713 for (i
= MAT_ATTRIB_FRONT_AMBIENT
; i
< MAT_ATTRIB_FRONT_INDEXES
; i
+=2)
714 if (memcmp( ctx
->Light
.Material
.Attrib
[i
],
715 ctx
->Light
.Material
.Attrib
[i
+1],
716 sizeof(GLfloat
)*4) != 0) {
723 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE
, fallback
);
727 static void radeonColorMaterial( struct gl_context
*ctx
, GLenum face
, GLenum mode
)
729 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
730 GLuint light_model_ctl1
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
732 light_model_ctl1
&= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT
) |
733 (3 << RADEON_AMBIENT_SOURCE_SHIFT
) |
734 (3 << RADEON_DIFFUSE_SOURCE_SHIFT
) |
735 (3 << RADEON_SPECULAR_SOURCE_SHIFT
));
737 if (ctx
->Light
.ColorMaterialEnabled
) {
738 GLuint mask
= ctx
->Light
._ColorMaterialBitmask
;
740 if (mask
& MAT_BIT_FRONT_EMISSION
) {
741 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
742 RADEON_EMISSIVE_SOURCE_SHIFT
);
745 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
746 RADEON_EMISSIVE_SOURCE_SHIFT
);
749 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
750 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
751 RADEON_AMBIENT_SOURCE_SHIFT
);
754 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
755 RADEON_AMBIENT_SOURCE_SHIFT
);
758 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
759 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
760 RADEON_DIFFUSE_SOURCE_SHIFT
);
763 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
764 RADEON_DIFFUSE_SOURCE_SHIFT
);
767 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
768 light_model_ctl1
|= (RADEON_LM_SOURCE_VERTEX_DIFFUSE
<<
769 RADEON_SPECULAR_SOURCE_SHIFT
);
772 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<<
773 RADEON_SPECULAR_SOURCE_SHIFT
);
779 light_model_ctl1
|= (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_EMISSIVE_SOURCE_SHIFT
) |
780 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_AMBIENT_SOURCE_SHIFT
) |
781 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_DIFFUSE_SOURCE_SHIFT
) |
782 (RADEON_LM_SOURCE_STATE_MULT
<< RADEON_SPECULAR_SOURCE_SHIFT
);
785 if (light_model_ctl1
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]) {
786 RADEON_STATECHANGE( rmesa
, tcl
);
787 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = light_model_ctl1
;
791 void radeonUpdateMaterial( struct gl_context
*ctx
)
793 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
794 GLfloat (*mat
)[4] = ctx
->Light
.Material
.Attrib
;
795 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( mtl
);
798 if (ctx
->Light
.ColorMaterialEnabled
)
799 mask
&= ~ctx
->Light
._ColorMaterialBitmask
;
801 if (RADEON_DEBUG
& RADEON_STATE
)
802 fprintf(stderr
, "%s\n", __func__
);
805 if (mask
& MAT_BIT_FRONT_EMISSION
) {
806 fcmd
[MTL_EMMISSIVE_RED
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][0];
807 fcmd
[MTL_EMMISSIVE_GREEN
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][1];
808 fcmd
[MTL_EMMISSIVE_BLUE
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][2];
809 fcmd
[MTL_EMMISSIVE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_EMISSION
][3];
811 if (mask
& MAT_BIT_FRONT_AMBIENT
) {
812 fcmd
[MTL_AMBIENT_RED
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][0];
813 fcmd
[MTL_AMBIENT_GREEN
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][1];
814 fcmd
[MTL_AMBIENT_BLUE
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][2];
815 fcmd
[MTL_AMBIENT_ALPHA
] = mat
[MAT_ATTRIB_FRONT_AMBIENT
][3];
817 if (mask
& MAT_BIT_FRONT_DIFFUSE
) {
818 fcmd
[MTL_DIFFUSE_RED
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][0];
819 fcmd
[MTL_DIFFUSE_GREEN
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][1];
820 fcmd
[MTL_DIFFUSE_BLUE
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][2];
821 fcmd
[MTL_DIFFUSE_ALPHA
] = mat
[MAT_ATTRIB_FRONT_DIFFUSE
][3];
823 if (mask
& MAT_BIT_FRONT_SPECULAR
) {
824 fcmd
[MTL_SPECULAR_RED
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][0];
825 fcmd
[MTL_SPECULAR_GREEN
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][1];
826 fcmd
[MTL_SPECULAR_BLUE
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][2];
827 fcmd
[MTL_SPECULAR_ALPHA
] = mat
[MAT_ATTRIB_FRONT_SPECULAR
][3];
829 if (mask
& MAT_BIT_FRONT_SHININESS
) {
830 fcmd
[MTL_SHININESS
] = mat
[MAT_ATTRIB_FRONT_SHININESS
][0];
833 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mtl
);
835 check_twoside_fallback( ctx
);
836 /* update_global_ambient( ctx );*/
841 * _MESA_NEW_NEED_EYE_COORDS
843 * Uses derived state from mesa:
852 * which are calculated in light.c and are correct for the current
853 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
854 * and _MESA_NEW_NEED_EYE_COORDS.
856 static void update_light( struct gl_context
*ctx
)
858 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
860 /* Have to check these, or have an automatic shortcircuit mechanism
861 * to remove noop statechanges. (Or just do a better job on the
865 GLuint tmp
= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
];
867 if (ctx
->_NeedEyeCoords
)
868 tmp
&= ~RADEON_LIGHT_IN_MODELSPACE
;
870 tmp
|= RADEON_LIGHT_IN_MODELSPACE
;
873 /* Leave this test disabled: (unexplained q3 lockup) (even with
876 if (tmp
!= rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
])
878 RADEON_STATECHANGE( rmesa
, tcl
);
879 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] = tmp
;
884 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( eye
);
885 fcmd
[EYE_X
] = ctx
->_EyeZDir
[0];
886 fcmd
[EYE_Y
] = ctx
->_EyeZDir
[1];
887 fcmd
[EYE_Z
] = - ctx
->_EyeZDir
[2];
888 fcmd
[EYE_RESCALE_FACTOR
] = ctx
->_ModelViewInvScale
;
889 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.eye
);
894 if (ctx
->Light
.Enabled
) {
895 GLbitfield mask
= ctx
->Light
._EnabledLights
;
897 const int p
= u_bit_scan(&mask
);
898 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
899 GLfloat
*fcmd
= (GLfloat
*)RADEON_DB_STATE( lit
[p
] );
901 if (l
->EyePosition
[3] == 0.0) {
902 COPY_3FV( &fcmd
[LIT_POSITION_X
], l
->_VP_inf_norm
);
903 COPY_3FV( &fcmd
[LIT_DIRECTION_X
], l
->_h_inf_norm
);
904 fcmd
[LIT_POSITION_W
] = 0;
905 fcmd
[LIT_DIRECTION_W
] = 0;
907 COPY_4V( &fcmd
[LIT_POSITION_X
], l
->_Position
);
908 fcmd
[LIT_DIRECTION_X
] = -l
->_NormSpotDirection
[0];
909 fcmd
[LIT_DIRECTION_Y
] = -l
->_NormSpotDirection
[1];
910 fcmd
[LIT_DIRECTION_Z
] = -l
->_NormSpotDirection
[2];
911 fcmd
[LIT_DIRECTION_W
] = 0;
914 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.lit
[p
] );
919 static void radeonLightfv( struct gl_context
*ctx
, GLenum light
,
920 GLenum pname
, const GLfloat
*params
)
922 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
923 GLint p
= light
- GL_LIGHT0
;
924 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
925 GLfloat
*fcmd
= (GLfloat
*)rmesa
->hw
.lit
[p
].cmd
;
932 update_light_colors( ctx
, p
);
935 case GL_SPOT_DIRECTION
:
936 /* picked up in update_light */
940 /* positions picked up in update_light, but can do flag here */
942 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
944 /* FIXME: Set RANGE_ATTEN only when needed */
946 flag
= RADEON_LIGHT_1_IS_LOCAL
;
948 flag
= RADEON_LIGHT_0_IS_LOCAL
;
950 RADEON_STATECHANGE(rmesa
, tcl
);
951 if (l
->EyePosition
[3] != 0.0F
)
952 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
954 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
958 case GL_SPOT_EXPONENT
:
959 RADEON_STATECHANGE(rmesa
, lit
[p
]);
960 fcmd
[LIT_SPOT_EXPONENT
] = params
[0];
963 case GL_SPOT_CUTOFF
: {
964 GLuint flag
= (p
&1) ? RADEON_LIGHT_1_IS_SPOT
: RADEON_LIGHT_0_IS_SPOT
;
965 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
967 RADEON_STATECHANGE(rmesa
, lit
[p
]);
968 fcmd
[LIT_SPOT_CUTOFF
] = l
->_CosCutoff
;
970 RADEON_STATECHANGE(rmesa
, tcl
);
971 if (l
->SpotCutoff
!= 180.0F
)
972 rmesa
->hw
.tcl
.cmd
[idx
] |= flag
;
974 rmesa
->hw
.tcl
.cmd
[idx
] &= ~flag
;
979 case GL_CONSTANT_ATTENUATION
:
980 RADEON_STATECHANGE(rmesa
, lit
[p
]);
981 fcmd
[LIT_ATTEN_CONST
] = params
[0];
982 if ( params
[0] == 0.0 )
983 fcmd
[LIT_ATTEN_CONST_INV
] = FLT_MAX
;
985 fcmd
[LIT_ATTEN_CONST_INV
] = 1.0 / params
[0];
987 case GL_LINEAR_ATTENUATION
:
988 RADEON_STATECHANGE(rmesa
, lit
[p
]);
989 fcmd
[LIT_ATTEN_LINEAR
] = params
[0];
991 case GL_QUADRATIC_ATTENUATION
:
992 RADEON_STATECHANGE(rmesa
, lit
[p
]);
993 fcmd
[LIT_ATTEN_QUADRATIC
] = params
[0];
999 /* Set RANGE_ATTEN only when needed */
1002 case GL_CONSTANT_ATTENUATION
:
1003 case GL_LINEAR_ATTENUATION
:
1004 case GL_QUADRATIC_ATTENUATION
:
1006 GLuint
*icmd
= (GLuint
*)RADEON_DB_STATE( tcl
);
1007 GLuint idx
= TCL_PER_LIGHT_CTL_0
+ p
/2;
1008 GLuint atten_flag
= ( p
&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1009 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN
;
1010 GLuint atten_const_flag
= ( p
&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1011 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN
;
1013 if ( l
->EyePosition
[3] == 0.0F
||
1014 ( ( fcmd
[LIT_ATTEN_CONST
] == 0.0 || fcmd
[LIT_ATTEN_CONST
] == 1.0 ) &&
1015 fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) ) {
1016 /* Disable attenuation */
1017 icmd
[idx
] &= ~atten_flag
;
1019 if ( fcmd
[LIT_ATTEN_QUADRATIC
] == 0.0 && fcmd
[LIT_ATTEN_LINEAR
] == 0.0 ) {
1020 /* Enable only constant portion of attenuation calculation */
1021 icmd
[idx
] |= ( atten_flag
| atten_const_flag
);
1023 /* Enable full attenuation calculation */
1024 icmd
[idx
] &= ~atten_const_flag
;
1025 icmd
[idx
] |= atten_flag
;
1029 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tcl
);
1040 static void radeonLightModelfv( struct gl_context
*ctx
, GLenum pname
,
1041 const GLfloat
*param
)
1043 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1046 case GL_LIGHT_MODEL_AMBIENT
:
1047 update_global_ambient( ctx
);
1050 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
1051 RADEON_STATECHANGE( rmesa
, tcl
);
1052 if (ctx
->Light
.Model
.LocalViewer
)
1053 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_LOCAL_VIEWER
;
1055 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_LOCAL_VIEWER
;
1058 case GL_LIGHT_MODEL_TWO_SIDE
:
1059 RADEON_STATECHANGE( rmesa
, tcl
);
1060 if (ctx
->Light
.Model
.TwoSide
)
1061 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= RADEON_LIGHT_TWOSIDE
;
1063 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_LIGHT_TWOSIDE
;
1065 check_twoside_fallback( ctx
);
1067 if (rmesa
->radeon
.TclFallback
) {
1068 radeonChooseRenderState( ctx
);
1069 radeonChooseVertexState( ctx
);
1073 case GL_LIGHT_MODEL_COLOR_CONTROL
:
1074 radeonUpdateSpecular(ctx
);
1082 static void radeonShadeModel( struct gl_context
*ctx
, GLenum mode
)
1084 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1085 GLuint s
= rmesa
->hw
.set
.cmd
[SET_SE_CNTL
];
1087 s
&= ~(RADEON_DIFFUSE_SHADE_MASK
|
1088 RADEON_ALPHA_SHADE_MASK
|
1089 RADEON_SPECULAR_SHADE_MASK
|
1090 RADEON_FOG_SHADE_MASK
);
1094 s
|= (RADEON_DIFFUSE_SHADE_FLAT
|
1095 RADEON_ALPHA_SHADE_FLAT
|
1096 RADEON_SPECULAR_SHADE_FLAT
|
1097 RADEON_FOG_SHADE_FLAT
);
1100 s
|= (RADEON_DIFFUSE_SHADE_GOURAUD
|
1101 RADEON_ALPHA_SHADE_GOURAUD
|
1102 RADEON_SPECULAR_SHADE_GOURAUD
|
1103 RADEON_FOG_SHADE_GOURAUD
);
1109 if ( rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] != s
) {
1110 RADEON_STATECHANGE( rmesa
, set
);
1111 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] = s
;
1116 /* =============================================================
1120 static void radeonClipPlane( struct gl_context
*ctx
, GLenum plane
, const GLfloat
*eq
)
1122 GLint p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
1123 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1124 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1126 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1127 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1128 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1129 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1130 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1133 static void radeonUpdateClipPlanes( struct gl_context
*ctx
)
1135 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1136 GLbitfield mask
= ctx
->Transform
.ClipPlanesEnabled
;
1139 const int p
= u_bit_scan(&mask
);
1140 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
1142 RADEON_STATECHANGE( rmesa
, ucp
[p
] );
1143 rmesa
->hw
.ucp
[p
].cmd
[UCP_X
] = ip
[0];
1144 rmesa
->hw
.ucp
[p
].cmd
[UCP_Y
] = ip
[1];
1145 rmesa
->hw
.ucp
[p
].cmd
[UCP_Z
] = ip
[2];
1146 rmesa
->hw
.ucp
[p
].cmd
[UCP_W
] = ip
[3];
1151 /* =============================================================
1156 radeonStencilFuncSeparate( struct gl_context
*ctx
, GLenum face
, GLenum func
,
1157 GLint ref
, GLuint mask
)
1159 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1160 GLuint refmask
= ((_mesa_get_stencil_ref(ctx
, 0) << RADEON_STENCIL_REF_SHIFT
) |
1161 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT
));
1163 RADEON_STATECHANGE( rmesa
, ctx
);
1164 RADEON_STATECHANGE( rmesa
, msk
);
1166 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~RADEON_STENCIL_TEST_MASK
;
1167 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~(RADEON_STENCIL_REF_MASK
|
1168 RADEON_STENCIL_VALUE_MASK
);
1170 switch ( ctx
->Stencil
.Function
[0] ) {
1172 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEVER
;
1175 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LESS
;
1178 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_EQUAL
;
1181 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_LEQUAL
;
1184 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GREATER
;
1187 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_NEQUAL
;
1190 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_GEQUAL
;
1193 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_TEST_ALWAYS
;
1197 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |= refmask
;
1201 radeonStencilMaskSeparate( struct gl_context
*ctx
, GLenum face
, GLuint mask
)
1203 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1205 RADEON_STATECHANGE( rmesa
, msk
);
1206 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] &= ~RADEON_STENCIL_WRITE_MASK
;
1207 rmesa
->hw
.msk
.cmd
[MSK_RB3D_STENCILREFMASK
] |=
1208 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT
);
1211 static void radeonStencilOpSeparate( struct gl_context
*ctx
, GLenum face
, GLenum fail
,
1212 GLenum zfail
, GLenum zpass
)
1214 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1216 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1217 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1218 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1220 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1221 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP
;
1222 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1223 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1224 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1225 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1227 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_BROKEN_STENCIL
) {
1228 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC
;
1229 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC
;
1230 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC
;
1231 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC
;
1232 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC
;
1233 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC
;
1236 tempRADEON_STENCIL_FAIL_DEC_WRAP
= RADEON_STENCIL_FAIL_DEC_WRAP
;
1237 tempRADEON_STENCIL_FAIL_INC_WRAP
= RADEON_STENCIL_FAIL_INC_WRAP
;
1238 tempRADEON_STENCIL_ZFAIL_DEC_WRAP
= RADEON_STENCIL_ZFAIL_DEC_WRAP
;
1239 tempRADEON_STENCIL_ZFAIL_INC_WRAP
= RADEON_STENCIL_ZFAIL_INC_WRAP
;
1240 tempRADEON_STENCIL_ZPASS_DEC_WRAP
= RADEON_STENCIL_ZPASS_DEC_WRAP
;
1241 tempRADEON_STENCIL_ZPASS_INC_WRAP
= RADEON_STENCIL_ZPASS_INC_WRAP
;
1244 RADEON_STATECHANGE( rmesa
, ctx
);
1245 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] &= ~(RADEON_STENCIL_FAIL_MASK
|
1246 RADEON_STENCIL_ZFAIL_MASK
|
1247 RADEON_STENCIL_ZPASS_MASK
);
1249 switch ( ctx
->Stencil
.FailFunc
[0] ) {
1251 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_KEEP
;
1254 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_ZERO
;
1257 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_REPLACE
;
1260 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INC
;
1263 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_DEC
;
1266 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_INC_WRAP
;
1269 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_FAIL_DEC_WRAP
;
1272 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_FAIL_INVERT
;
1276 switch ( ctx
->Stencil
.ZFailFunc
[0] ) {
1278 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_KEEP
;
1281 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_ZERO
;
1284 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_REPLACE
;
1287 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INC
;
1290 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_DEC
;
1293 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP
;
1296 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP
;
1299 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZFAIL_INVERT
;
1303 switch ( ctx
->Stencil
.ZPassFunc
[0] ) {
1305 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_KEEP
;
1308 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_ZERO
;
1311 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_REPLACE
;
1314 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INC
;
1317 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_DEC
;
1320 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_INC_WRAP
;
1323 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP
;
1326 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_ZSTENCILCNTL
] |= RADEON_STENCIL_ZPASS_INVERT
;
1333 /* =============================================================
1334 * Window position and viewport transformation
1338 * To correctly position primitives:
1340 #define SUBPIXEL_X 0.125
1341 #define SUBPIXEL_Y 0.125
1345 * Called when window size or position changes or viewport or depth range
1346 * state is changed. We update the hardware viewport state here.
1348 void radeonUpdateWindow( struct gl_context
*ctx
)
1350 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1351 __DRIdrawable
*dPriv
= radeon_get_drawable(&rmesa
->radeon
);
1352 GLfloat xoffset
= 0.0;
1353 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->h
: 0;
1354 const GLboolean render_to_fbo
= (ctx
->DrawBuffer
? _mesa_is_user_fbo(ctx
->DrawBuffer
) : 0);
1355 float scale
[3], translate
[3];
1356 GLfloat y_scale
, y_bias
;
1358 if (render_to_fbo
) {
1366 _mesa_get_viewport_xform(ctx
, 0, scale
, translate
);
1367 float_ui32_type sx
= { scale
[0] };
1368 float_ui32_type sy
= { scale
[1] * y_scale
};
1369 float_ui32_type sz
= { scale
[2] };
1370 float_ui32_type tx
= { translate
[0] + xoffset
+ SUBPIXEL_X
};
1371 float_ui32_type ty
= { (translate
[1] * y_scale
) + y_bias
+ SUBPIXEL_Y
};
1372 float_ui32_type tz
= { translate
[2] };
1374 RADEON_STATECHANGE( rmesa
, vpt
);
1376 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XSCALE
] = sx
.ui32
;
1377 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = tx
.ui32
;
1378 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YSCALE
] = sy
.ui32
;
1379 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = ty
.ui32
;
1380 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZSCALE
] = sz
.ui32
;
1381 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_ZOFFSET
] = tz
.ui32
;
1385 static void radeonViewport(struct gl_context
*ctx
)
1387 /* Don't pipeline viewport changes, conflict with window offset
1388 * setting below. Could apply deltas to rescue pipelined viewport
1389 * values, or keep the originals hanging around.
1391 radeonUpdateWindow( ctx
);
1393 radeon_viewport(ctx
);
1396 static void radeonDepthRange(struct gl_context
*ctx
)
1398 radeonUpdateWindow( ctx
);
1401 /* =============================================================
1405 static void radeonRenderMode( struct gl_context
*ctx
, GLenum mode
)
1407 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1408 FALLBACK( rmesa
, RADEON_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1412 static GLuint radeon_rop_tab
[] = {
1415 RADEON_ROP_AND_REVERSE
,
1417 RADEON_ROP_AND_INVERTED
,
1424 RADEON_ROP_OR_REVERSE
,
1425 RADEON_ROP_COPY_INVERTED
,
1426 RADEON_ROP_OR_INVERTED
,
1431 static void radeonLogicOpCode( struct gl_context
*ctx
, GLenum opcode
)
1433 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1434 GLuint rop
= (GLuint
)opcode
- GL_CLEAR
;
1438 RADEON_STATECHANGE( rmesa
, msk
);
1439 rmesa
->hw
.msk
.cmd
[MSK_RB3D_ROPCNTL
] = radeon_rop_tab
[rop
];
1442 /* =============================================================
1443 * State enable/disable
1446 static void radeonEnable( struct gl_context
*ctx
, GLenum cap
, GLboolean state
)
1448 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1451 if ( RADEON_DEBUG
& RADEON_STATE
)
1452 fprintf( stderr
, "%s( %s = %s )\n", __func__
,
1453 _mesa_enum_to_string( cap
),
1454 state
? "GL_TRUE" : "GL_FALSE" );
1457 /* Fast track this one...
1465 RADEON_STATECHANGE( rmesa
, ctx
);
1467 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ALPHA_TEST_ENABLE
;
1469 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ALPHA_TEST_ENABLE
;
1474 RADEON_STATECHANGE( rmesa
, ctx
);
1476 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ALPHA_BLEND_ENABLE
;
1478 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ALPHA_BLEND_ENABLE
;
1480 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1481 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1482 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1484 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1487 /* Catch a possible fallback:
1490 ctx
->Driver
.BlendEquationSeparate( ctx
,
1491 ctx
->Color
.Blend
[0].EquationRGB
,
1492 ctx
->Color
.Blend
[0].EquationA
);
1493 ctx
->Driver
.BlendFuncSeparate( ctx
, ctx
->Color
.Blend
[0].SrcRGB
,
1494 ctx
->Color
.Blend
[0].DstRGB
,
1495 ctx
->Color
.Blend
[0].SrcA
,
1496 ctx
->Color
.Blend
[0].DstA
);
1499 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_FUNC
, GL_FALSE
);
1500 FALLBACK( rmesa
, RADEON_FALLBACK_BLEND_EQ
, GL_FALSE
);
1504 case GL_CLIP_PLANE0
:
1505 case GL_CLIP_PLANE1
:
1506 case GL_CLIP_PLANE2
:
1507 case GL_CLIP_PLANE3
:
1508 case GL_CLIP_PLANE4
:
1509 case GL_CLIP_PLANE5
:
1510 p
= cap
-GL_CLIP_PLANE0
;
1511 RADEON_STATECHANGE( rmesa
, tcl
);
1513 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] |= (RADEON_UCP_ENABLE_0
<<p
);
1514 radeonClipPlane( ctx
, cap
, NULL
);
1517 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~(RADEON_UCP_ENABLE_0
<<p
);
1521 case GL_COLOR_MATERIAL
:
1522 radeonColorMaterial( ctx
, 0, 0 );
1523 radeonUpdateMaterial( ctx
);
1527 radeonCullFace( ctx
, 0 );
1531 RADEON_STATECHANGE(rmesa
, ctx
);
1533 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_Z_ENABLE
;
1535 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_Z_ENABLE
;
1540 RADEON_STATECHANGE(rmesa
, ctx
);
1542 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_DITHER_ENABLE
;
1543 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~rmesa
->radeon
.state
.color
.roundEnable
;
1545 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_DITHER_ENABLE
;
1546 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= rmesa
->radeon
.state
.color
.roundEnable
;
1551 RADEON_STATECHANGE(rmesa
, ctx
);
1553 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_FOG_ENABLE
;
1554 radeonFogfv( ctx
, GL_FOG_MODE
, NULL
);
1556 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_FOG_ENABLE
;
1557 RADEON_STATECHANGE(rmesa
, tcl
);
1558 rmesa
->hw
.tcl
.cmd
[TCL_UCP_VERT_BLEND_CTL
] &= ~RADEON_TCL_FOG_MASK
;
1560 radeonUpdateSpecular( ctx
); /* for PK_SPEC */
1561 _mesa_allow_light_in_model( ctx
, !state
);
1572 RADEON_STATECHANGE(rmesa
, tcl
);
1573 p
= cap
- GL_LIGHT0
;
1575 flag
= (RADEON_LIGHT_1_ENABLE
|
1576 RADEON_LIGHT_1_ENABLE_AMBIENT
|
1577 RADEON_LIGHT_1_ENABLE_SPECULAR
);
1579 flag
= (RADEON_LIGHT_0_ENABLE
|
1580 RADEON_LIGHT_0_ENABLE_AMBIENT
|
1581 RADEON_LIGHT_0_ENABLE_SPECULAR
);
1584 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] |= flag
;
1586 rmesa
->hw
.tcl
.cmd
[p
/2 + TCL_PER_LIGHT_CTL_0
] &= ~flag
;
1590 update_light_colors( ctx
, p
);
1594 RADEON_STATECHANGE(rmesa
, tcl
);
1595 radeonUpdateSpecular(ctx
);
1596 check_twoside_fallback( ctx
);
1599 case GL_LINE_SMOOTH
:
1600 RADEON_STATECHANGE( rmesa
, ctx
);
1602 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_LINE
;
1604 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_LINE
;
1608 case GL_LINE_STIPPLE
:
1609 RADEON_STATECHANGE( rmesa
, ctx
);
1611 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_PATTERN_ENABLE
;
1613 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_PATTERN_ENABLE
;
1617 case GL_COLOR_LOGIC_OP
:
1618 RADEON_STATECHANGE( rmesa
, ctx
);
1619 if ( (ctx
->Color
.ColorLogicOpEnabled
|| (ctx
->Color
.BlendEnabled
1620 && ctx
->Color
.Blend
[0].EquationRGB
== GL_LOGIC_OP
)) ) {
1621 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_ROP_ENABLE
;
1623 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_ROP_ENABLE
;
1628 RADEON_STATECHANGE( rmesa
, tcl
);
1630 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_NORMALIZE_NORMALS
;
1632 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_NORMALIZE_NORMALS
;
1636 case GL_POLYGON_OFFSET_POINT
:
1637 RADEON_STATECHANGE( rmesa
, set
);
1639 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_POINT
;
1641 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_POINT
;
1645 case GL_POLYGON_OFFSET_LINE
:
1646 RADEON_STATECHANGE( rmesa
, set
);
1648 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_LINE
;
1650 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_LINE
;
1654 case GL_POLYGON_OFFSET_FILL
:
1655 RADEON_STATECHANGE( rmesa
, set
);
1657 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] |= RADEON_ZBIAS_ENABLE_TRI
;
1659 rmesa
->hw
.set
.cmd
[SET_SE_CNTL
] &= ~RADEON_ZBIAS_ENABLE_TRI
;
1663 case GL_POLYGON_SMOOTH
:
1664 RADEON_STATECHANGE( rmesa
, ctx
);
1666 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_ANTI_ALIAS_POLY
;
1668 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_ANTI_ALIAS_POLY
;
1672 case GL_POLYGON_STIPPLE
:
1673 RADEON_STATECHANGE(rmesa
, ctx
);
1675 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= RADEON_STIPPLE_ENABLE
;
1677 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~RADEON_STIPPLE_ENABLE
;
1681 case GL_RESCALE_NORMAL_EXT
: {
1682 GLboolean tmp
= ctx
->_NeedEyeCoords
? state
: !state
;
1683 RADEON_STATECHANGE( rmesa
, tcl
);
1685 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1687 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1692 case GL_SCISSOR_TEST
:
1693 radeon_firevertices(&rmesa
->radeon
);
1694 rmesa
->radeon
.state
.scissor
.enabled
= state
;
1695 radeonUpdateScissor( ctx
);
1698 case GL_STENCIL_TEST
:
1700 GLboolean hw_stencil
= GL_FALSE
;
1701 if (ctx
->DrawBuffer
) {
1702 struct radeon_renderbuffer
*rrbStencil
1703 = radeon_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
1704 hw_stencil
= (rrbStencil
&& rrbStencil
->bo
);
1708 RADEON_STATECHANGE( rmesa
, ctx
);
1710 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] |= RADEON_STENCIL_ENABLE
;
1712 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_CNTL
] &= ~RADEON_STENCIL_ENABLE
;
1715 FALLBACK( rmesa
, RADEON_FALLBACK_STENCIL
, state
);
1720 case GL_TEXTURE_GEN_Q
:
1721 case GL_TEXTURE_GEN_R
:
1722 case GL_TEXTURE_GEN_S
:
1723 case GL_TEXTURE_GEN_T
:
1724 /* Picked up in radeonUpdateTextureState.
1726 rmesa
->recheck_texgen
[ctx
->Texture
.CurrentUnit
] = GL_TRUE
;
1729 case GL_COLOR_SUM_EXT
:
1730 radeonUpdateSpecular ( ctx
);
1739 static void radeonLightingSpaceChange( struct gl_context
*ctx
)
1741 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1743 RADEON_STATECHANGE( rmesa
, tcl
);
1745 if (RADEON_DEBUG
& RADEON_STATE
)
1746 fprintf(stderr
, "%s %d BEFORE %x\n", __func__
, ctx
->_NeedEyeCoords
,
1747 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1749 if (ctx
->_NeedEyeCoords
)
1750 tmp
= ctx
->Transform
.RescaleNormals
;
1752 tmp
= !ctx
->Transform
.RescaleNormals
;
1755 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] |= RADEON_RESCALE_NORMALS
;
1757 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
] &= ~RADEON_RESCALE_NORMALS
;
1760 if (RADEON_DEBUG
& RADEON_STATE
)
1761 fprintf(stderr
, "%s %d AFTER %x\n", __func__
, ctx
->_NeedEyeCoords
,
1762 rmesa
->hw
.tcl
.cmd
[TCL_LIGHT_MODEL_CTL
]);
1765 /* =============================================================
1766 * Deferred state management - matrices, textures, other?
1770 void radeonUploadTexMatrix( r100ContextPtr rmesa
,
1771 int unit
, GLboolean swapcols
)
1773 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1774 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1775 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1776 texgen generates all 4 coords, at least tests with projtex indicated that.
1777 So: if we need the q coord in the end (solely determined by the texture
1778 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1779 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1780 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1781 will get submitted in the "wrong", i.e. 3rd, slot.
1782 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1783 size and using the texture matrix to swap the r and q coords around (ut2k3
1784 does exactly that), so we don't need the 3rd / 4th column swap - still need
1785 the 3rd / 4th row swap of course. This will potentially break for apps which
1786 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1787 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1788 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1789 incredibly hard to detect so we can't just fallback in such a case. Assume
1790 it never happens... - rs
1793 int idx
= TEXMAT_0
+ unit
;
1794 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] )) + MAT_ELT_0
;
1796 struct gl_texture_unit tUnit
= rmesa
->radeon
.glCtx
.Texture
.Unit
[unit
];
1797 GLfloat
*src
= rmesa
->tmpmat
[unit
].m
;
1799 rmesa
->TexMatColSwap
&= ~(1 << unit
);
1800 if (!tUnit
._Current
||
1801 (tUnit
._Current
->Target
!= GL_TEXTURE_3D
&&
1802 tUnit
._Current
->Target
!= GL_TEXTURE_CUBE_MAP
)) {
1804 rmesa
->TexMatColSwap
|= 1 << unit
;
1805 /* attention some elems are swapped 2 times! */
1818 /* those last 4 are probably never used */
1825 for (i
= 0; i
< 2; i
++) {
1829 *dest
++ = src
[i
+12];
1831 for (i
= 3; i
>= 2; i
--) {
1835 *dest
++ = src
[i
+12];
1840 for (i
= 0 ; i
< 4 ; i
++) {
1844 *dest
++ = src
[i
+12];
1848 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1852 static void upload_matrix( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1854 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1858 for (i
= 0 ; i
< 4 ; i
++) {
1862 *dest
++ = src
[i
+12];
1865 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1868 static void upload_matrix_t( r100ContextPtr rmesa
, GLfloat
*src
, int idx
)
1870 float *dest
= ((float *)RADEON_DB_STATE( mat
[idx
] ))+MAT_ELT_0
;
1871 memcpy(dest
, src
, 16*sizeof(float));
1872 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.mat
[idx
] );
1876 static void update_texturematrix( struct gl_context
*ctx
)
1878 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
1879 GLuint tpc
= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
];
1880 GLuint vs
= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
];
1882 GLuint texMatEnabled
= 0;
1883 rmesa
->NeedTexMatrix
= 0;
1884 rmesa
->TexMatColSwap
= 0;
1886 for (unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
1887 if (ctx
->Texture
.Unit
[unit
]._Current
) {
1888 GLboolean needMatrix
= GL_FALSE
;
1889 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
) {
1890 needMatrix
= GL_TRUE
;
1891 texMatEnabled
|= (RADEON_TEXGEN_TEXMAT_0_ENABLE
|
1892 RADEON_TEXMAT_0_ENABLE
) << unit
;
1894 if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1895 /* Need to preconcatenate any active texgen
1896 * obj/eyeplane matrices:
1898 _math_matrix_mul_matrix( &rmesa
->tmpmat
[unit
],
1899 ctx
->TextureMatrixStack
[unit
].Top
,
1900 &rmesa
->TexGenMatrix
[unit
] );
1903 _math_matrix_copy( &rmesa
->tmpmat
[unit
],
1904 ctx
->TextureMatrixStack
[unit
].Top
);
1907 else if (rmesa
->TexGenEnabled
& (RADEON_TEXMAT_0_ENABLE
<< unit
)) {
1908 _math_matrix_copy( &rmesa
->tmpmat
[unit
], &rmesa
->TexGenMatrix
[unit
] );
1909 needMatrix
= GL_TRUE
;
1912 rmesa
->NeedTexMatrix
|= 1 << unit
;
1913 radeonUploadTexMatrix( rmesa
, unit
,
1914 !ctx
->Texture
.Unit
[unit
].TexGenEnabled
);
1919 tpc
= (texMatEnabled
| rmesa
->TexGenEnabled
);
1921 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1922 vs
&= ~((RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_0_OUTPUT_SHIFT
) |
1923 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_1_OUTPUT_SHIFT
) |
1924 (RADEON_TCL_TEX_COMPUTED_TEX_0
<< RADEON_TCL_TEX_2_OUTPUT_SHIFT
));
1926 vs
|= (((tpc
& RADEON_TEXGEN_TEXMAT_0_ENABLE
) <<
1927 (RADEON_TCL_TEX_0_OUTPUT_SHIFT
+ 3)) |
1928 ((tpc
& RADEON_TEXGEN_TEXMAT_1_ENABLE
) <<
1929 (RADEON_TCL_TEX_1_OUTPUT_SHIFT
+ 2)) |
1930 ((tpc
& RADEON_TEXGEN_TEXMAT_2_ENABLE
) <<
1931 (RADEON_TCL_TEX_2_OUTPUT_SHIFT
+ 1)));
1933 if (tpc
!= rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] ||
1934 vs
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
]) {
1936 RADEON_STATECHANGE(rmesa
, tcl
);
1937 rmesa
->hw
.tcl
.cmd
[TCL_TEXTURE_PROC_CTL
] = tpc
;
1938 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXSEL
] = vs
;
1942 GLboolean
r100ValidateBuffers(struct gl_context
*ctx
)
1944 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1945 struct radeon_renderbuffer
*rrb
;
1948 radeon_cs_space_reset_bos(rmesa
->radeon
.cmdbuf
.cs
);
1950 rrb
= radeon_get_colorbuffer(&rmesa
->radeon
);
1952 if (rrb
&& rrb
->bo
) {
1953 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
1954 0, RADEON_GEM_DOMAIN_VRAM
);
1958 rrb
= radeon_get_depthbuffer(&rmesa
->radeon
);
1960 if (rrb
&& rrb
->bo
) {
1961 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, rrb
->bo
,
1962 0, RADEON_GEM_DOMAIN_VRAM
);
1965 for (i
= 0; i
< ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
; ++i
) {
1968 if (!ctx
->Texture
.Unit
[i
]._Current
)
1971 t
= rmesa
->state
.texture
.unit
[i
].texobj
;
1975 if (t
->image_override
&& t
->bo
)
1976 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->bo
,
1977 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
1979 radeon_cs_space_add_persistent_bo(rmesa
->radeon
.cmdbuf
.cs
, t
->mt
->bo
,
1980 RADEON_GEM_DOMAIN_GTT
| RADEON_GEM_DOMAIN_VRAM
, 0);
1983 ret
= radeon_cs_space_check_with_bo(rmesa
->radeon
.cmdbuf
.cs
, first_elem(&rmesa
->radeon
.dma
.reserved
)->bo
, RADEON_GEM_DOMAIN_GTT
, 0);
1989 GLboolean
radeonValidateState( struct gl_context
*ctx
)
1991 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1992 GLuint new_state
= rmesa
->radeon
.NewGLState
;
1994 if (new_state
& _NEW_BUFFERS
) {
1995 _mesa_update_framebuffer(ctx
, ctx
->ReadBuffer
, ctx
->DrawBuffer
);
1996 /* this updates the DrawBuffer's Width/Height if it's a FBO */
1997 _mesa_update_draw_buffer_bounds(ctx
, ctx
->DrawBuffer
);
1998 RADEON_STATECHANGE(rmesa
, ctx
);
2001 if (new_state
& _NEW_TEXTURE
) {
2002 radeonUpdateTextureState( ctx
);
2003 new_state
|= rmesa
->radeon
.NewGLState
; /* may add TEXTURE_MATRIX */
2006 /* we need to do a space check here */
2007 if (!r100ValidateBuffers(ctx
))
2010 /* Need an event driven matrix update?
2012 if (new_state
& (_NEW_MODELVIEW
|_NEW_PROJECTION
))
2013 upload_matrix( rmesa
, ctx
->_ModelProjectMatrix
.m
, MODEL_PROJ
);
2015 /* Need these for lighting (shouldn't upload otherwise)
2017 if (new_state
& (_NEW_MODELVIEW
)) {
2018 upload_matrix( rmesa
, ctx
->ModelviewMatrixStack
.Top
->m
, MODEL
);
2019 upload_matrix_t( rmesa
, ctx
->ModelviewMatrixStack
.Top
->inv
, MODEL_IT
);
2022 /* Does this need to be triggered on eg. modelview for
2023 * texgen-derived objplane/eyeplane matrices?
2025 if (new_state
& _NEW_TEXTURE_MATRIX
) {
2026 update_texturematrix( ctx
);
2029 if (new_state
& (_NEW_LIGHT
|_NEW_MODELVIEW
|_MESA_NEW_NEED_EYE_COORDS
)) {
2030 update_light( ctx
);
2033 /* emit all active clip planes if projection matrix changes.
2035 if (new_state
& (_NEW_PROJECTION
)) {
2036 if (ctx
->Transform
.ClipPlanesEnabled
)
2037 radeonUpdateClipPlanes( ctx
);
2041 rmesa
->radeon
.NewGLState
= 0;
2047 static void radeonInvalidateState(struct gl_context
*ctx
)
2049 GLuint new_state
= ctx
->NewState
;
2051 if (new_state
& (_NEW_SCISSOR
| _NEW_BUFFERS
| _NEW_VIEWPORT
))
2052 _mesa_update_draw_buffer_bounds(ctx
, ctx
->DrawBuffer
);
2054 _swrast_InvalidateState( ctx
, new_state
);
2055 _swsetup_InvalidateState( ctx
, new_state
);
2056 _tnl_InvalidateState( ctx
, new_state
);
2057 R100_CONTEXT(ctx
)->radeon
.NewGLState
|= new_state
;
2061 /* A hack. Need a faster way to find this out.
2063 static GLboolean
check_material( struct gl_context
*ctx
)
2065 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2068 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
;
2069 i
< _TNL_ATTRIB_MAT_BACK_INDEXES
;
2071 if (tnl
->vb
.AttribPtr
[i
] &&
2072 tnl
->vb
.AttribPtr
[i
]->stride
)
2079 static void radeonWrapRunPipeline( struct gl_context
*ctx
)
2081 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
2082 GLboolean has_material
;
2085 fprintf(stderr
, "%s, newstate: %x\n", __func__
, rmesa
->radeon
.NewGLState
);
2089 if (rmesa
->radeon
.NewGLState
)
2090 if (!radeonValidateState( ctx
))
2091 FALLBACK(rmesa
, RADEON_FALLBACK_TEXTURE
, GL_TRUE
);
2093 has_material
= (ctx
->Light
.Enabled
&& check_material( ctx
));
2096 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_TRUE
);
2099 /* Run the pipeline.
2101 _tnl_run_pipeline( ctx
);
2104 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_MATERIAL
, GL_FALSE
);
2108 static void radeonPolygonStipple( struct gl_context
*ctx
, const GLubyte
*mask
)
2110 r100ContextPtr r100
= R100_CONTEXT(ctx
);
2113 radeon_firevertices(&r100
->radeon
);
2115 RADEON_STATECHANGE(r100
, stp
);
2117 /* Must flip pattern upside down.
2119 for ( i
= 31 ; i
>= 0; i
--) {
2120 r100
->hw
.stp
.cmd
[3 + i
] = ((GLuint
*) mask
)[i
];
2125 /* Initialize the driver's state functions.
2126 * Many of the ctx->Driver functions might have been initialized to
2127 * software defaults in the earlier _mesa_init_driver_functions() call.
2129 void radeonInitStateFuncs( struct gl_context
*ctx
)
2131 ctx
->Driver
.UpdateState
= radeonInvalidateState
;
2132 ctx
->Driver
.LightingSpaceChange
= radeonLightingSpaceChange
;
2134 ctx
->Driver
.DrawBuffer
= radeonDrawBuffer
;
2135 ctx
->Driver
.ReadBuffer
= radeonReadBuffer
;
2136 ctx
->Driver
.CopyPixels
= _mesa_meta_CopyPixels
;
2137 ctx
->Driver
.DrawPixels
= _mesa_meta_DrawPixels
;
2138 ctx
->Driver
.ReadPixels
= radeonReadPixels
;
2140 ctx
->Driver
.AlphaFunc
= radeonAlphaFunc
;
2141 ctx
->Driver
.BlendEquationSeparate
= radeonBlendEquationSeparate
;
2142 ctx
->Driver
.BlendFuncSeparate
= radeonBlendFuncSeparate
;
2143 ctx
->Driver
.ClipPlane
= radeonClipPlane
;
2144 ctx
->Driver
.ColorMask
= radeonColorMask
;
2145 ctx
->Driver
.CullFace
= radeonCullFace
;
2146 ctx
->Driver
.DepthFunc
= radeonDepthFunc
;
2147 ctx
->Driver
.DepthMask
= radeonDepthMask
;
2148 ctx
->Driver
.DepthRange
= radeonDepthRange
;
2149 ctx
->Driver
.Enable
= radeonEnable
;
2150 ctx
->Driver
.Fogfv
= radeonFogfv
;
2151 ctx
->Driver
.FrontFace
= radeonFrontFace
;
2152 ctx
->Driver
.LightModelfv
= radeonLightModelfv
;
2153 ctx
->Driver
.Lightfv
= radeonLightfv
;
2154 ctx
->Driver
.LineStipple
= radeonLineStipple
;
2155 ctx
->Driver
.LineWidth
= radeonLineWidth
;
2156 ctx
->Driver
.LogicOpcode
= radeonLogicOpCode
;
2157 ctx
->Driver
.PolygonMode
= radeonPolygonMode
;
2158 ctx
->Driver
.PolygonOffset
= radeonPolygonOffset
;
2159 ctx
->Driver
.PolygonStipple
= radeonPolygonStipple
;
2160 ctx
->Driver
.RenderMode
= radeonRenderMode
;
2161 ctx
->Driver
.Scissor
= radeonScissor
;
2162 ctx
->Driver
.ShadeModel
= radeonShadeModel
;
2163 ctx
->Driver
.StencilFuncSeparate
= radeonStencilFuncSeparate
;
2164 ctx
->Driver
.StencilMaskSeparate
= radeonStencilMaskSeparate
;
2165 ctx
->Driver
.StencilOpSeparate
= radeonStencilOpSeparate
;
2166 ctx
->Driver
.Viewport
= radeonViewport
;
2168 TNL_CONTEXT(ctx
)->Driver
.NotifyMaterialChange
= radeonUpdateMaterial
;
2169 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= radeonWrapRunPipeline
;