1 /**************************************************************************
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/simple_list.h"
43 #include "main/state.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "drivers/common/meta.h"
51 #include "radeon_context.h"
52 #include "radeon_mipmap_tree.h"
53 #include "radeon_ioctl.h"
54 #include "radeon_state.h"
55 #include "radeon_tcl.h"
56 #include "radeon_tex.h"
57 #include "radeon_swtcl.h"
59 static void radeonUpdateSpecular( struct gl_context *ctx );
61 /* =============================================================
65 static void radeonAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
67 r100ContextPtr rmesa = R100_CONTEXT(ctx);
68 int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC];
71 CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
73 RADEON_STATECHANGE( rmesa, ctx );
75 pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK);
76 pp_misc |= (refByte & RADEON_REF_ALPHA_MASK);
80 pp_misc |= RADEON_ALPHA_TEST_FAIL;
83 pp_misc |= RADEON_ALPHA_TEST_LESS;
86 pp_misc |= RADEON_ALPHA_TEST_EQUAL;
89 pp_misc |= RADEON_ALPHA_TEST_LEQUAL;
92 pp_misc |= RADEON_ALPHA_TEST_GREATER;
95 pp_misc |= RADEON_ALPHA_TEST_NEQUAL;
98 pp_misc |= RADEON_ALPHA_TEST_GEQUAL;
101 pp_misc |= RADEON_ALPHA_TEST_PASS;
105 rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
108 static void radeonBlendEquationSeparate( struct gl_context *ctx,
109 GLenum modeRGB, GLenum modeA )
111 r100ContextPtr rmesa = R100_CONTEXT(ctx);
112 GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK;
113 GLboolean fallback = GL_FALSE;
115 assert( modeRGB == modeA );
120 b |= RADEON_COMB_FCN_ADD_CLAMP;
123 case GL_FUNC_SUBTRACT:
124 b |= RADEON_COMB_FCN_SUB_CLAMP;
128 if (ctx->Color.BlendEnabled)
131 b |= RADEON_COMB_FCN_ADD_CLAMP;
135 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, fallback );
137 RADEON_STATECHANGE( rmesa, ctx );
138 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
139 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
140 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
141 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
143 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
148 static void radeonBlendFuncSeparate( struct gl_context *ctx,
149 GLenum sfactorRGB, GLenum dfactorRGB,
150 GLenum sfactorA, GLenum dfactorA )
152 r100ContextPtr rmesa = R100_CONTEXT(ctx);
153 GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] &
154 ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
155 GLboolean fallback = GL_FALSE;
157 switch ( ctx->Color.Blend[0].SrcRGB ) {
159 b |= RADEON_SRC_BLEND_GL_ZERO;
162 b |= RADEON_SRC_BLEND_GL_ONE;
165 b |= RADEON_SRC_BLEND_GL_DST_COLOR;
167 case GL_ONE_MINUS_DST_COLOR:
168 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
171 b |= RADEON_SRC_BLEND_GL_SRC_COLOR;
173 case GL_ONE_MINUS_SRC_COLOR:
174 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR;
177 b |= RADEON_SRC_BLEND_GL_SRC_ALPHA;
179 case GL_ONE_MINUS_SRC_ALPHA:
180 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
183 b |= RADEON_SRC_BLEND_GL_DST_ALPHA;
185 case GL_ONE_MINUS_DST_ALPHA:
186 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
188 case GL_SRC_ALPHA_SATURATE:
189 b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
191 case GL_CONSTANT_COLOR:
192 case GL_ONE_MINUS_CONSTANT_COLOR:
193 case GL_CONSTANT_ALPHA:
194 case GL_ONE_MINUS_CONSTANT_ALPHA:
195 if (ctx->Color.BlendEnabled)
198 b |= RADEON_SRC_BLEND_GL_ONE;
204 switch ( ctx->Color.Blend[0].DstRGB ) {
206 b |= RADEON_DST_BLEND_GL_ZERO;
209 b |= RADEON_DST_BLEND_GL_ONE;
212 b |= RADEON_DST_BLEND_GL_SRC_COLOR;
214 case GL_ONE_MINUS_SRC_COLOR:
215 b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR;
218 b |= RADEON_DST_BLEND_GL_SRC_ALPHA;
220 case GL_ONE_MINUS_SRC_ALPHA:
221 b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
224 b |= RADEON_DST_BLEND_GL_DST_COLOR;
226 case GL_ONE_MINUS_DST_COLOR:
227 b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR;
230 b |= RADEON_DST_BLEND_GL_DST_ALPHA;
232 case GL_ONE_MINUS_DST_ALPHA:
233 b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA;
235 case GL_CONSTANT_COLOR:
236 case GL_ONE_MINUS_CONSTANT_COLOR:
237 case GL_CONSTANT_ALPHA:
238 case GL_ONE_MINUS_CONSTANT_ALPHA:
239 if (ctx->Color.BlendEnabled)
242 b |= RADEON_DST_BLEND_GL_ZERO;
248 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback );
250 RADEON_STATECHANGE( rmesa, ctx );
251 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
256 /* =============================================================
260 static void radeonDepthFunc( struct gl_context *ctx, GLenum func )
262 r100ContextPtr rmesa = R100_CONTEXT(ctx);
264 RADEON_STATECHANGE( rmesa, ctx );
265 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK;
267 switch ( ctx->Depth.Func ) {
269 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEVER;
272 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LESS;
275 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_EQUAL;
278 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LEQUAL;
281 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GREATER;
284 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEQUAL;
287 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GEQUAL;
290 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_ALWAYS;
296 static void radeonDepthMask( struct gl_context *ctx, GLboolean flag )
298 r100ContextPtr rmesa = R100_CONTEXT(ctx);
299 RADEON_STATECHANGE( rmesa, ctx );
301 if ( ctx->Depth.Mask ) {
302 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_WRITE_ENABLE;
304 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_WRITE_ENABLE;
308 static void radeonClearDepth( struct gl_context *ctx, GLclampd d )
310 r100ContextPtr rmesa = R100_CONTEXT(ctx);
311 GLuint format = (rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &
312 RADEON_DEPTH_FORMAT_MASK);
315 case RADEON_DEPTH_FORMAT_16BIT_INT_Z:
316 rmesa->radeon.state.depth.clear = d * 0x0000ffff;
318 case RADEON_DEPTH_FORMAT_24BIT_INT_Z:
319 rmesa->radeon.state.depth.clear = d * 0x00ffffff;
325 /* =============================================================
330 static void radeonFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
332 r100ContextPtr rmesa = R100_CONTEXT(ctx);
333 union { int i; float f; } c, d;
338 if (!ctx->Fog.Enabled)
340 RADEON_STATECHANGE(rmesa, tcl);
341 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
342 switch (ctx->Fog.Mode) {
344 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
347 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
350 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
359 if (!ctx->Fog.Enabled)
361 c.i = rmesa->hw.fog.cmd[FOG_C];
362 d.i = rmesa->hw.fog.cmd[FOG_D];
363 switch (ctx->Fog.Mode) {
366 /* While this is the opposite sign from the DDK, it makes the fog test
367 * pass, and matches r200.
369 d.f = -ctx->Fog.Density;
373 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
376 if (ctx->Fog.Start == ctx->Fog.End) {
380 c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
381 /* While this is the opposite sign from the DDK, it makes the fog
382 * test pass, and matches r200.
384 d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
390 if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
391 RADEON_STATECHANGE( rmesa, fog );
392 rmesa->hw.fog.cmd[FOG_C] = c.i;
393 rmesa->hw.fog.cmd[FOG_D] = d.i;
397 RADEON_STATECHANGE( rmesa, ctx );
398 UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
399 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
400 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
401 radeonPackColor( 4, col[0], col[1], col[2], 0 );
403 case GL_FOG_COORD_SRC:
404 radeonUpdateSpecular( ctx );
411 /* =============================================================
415 static void radeonCullFace( struct gl_context *ctx, GLenum unused )
417 r100ContextPtr rmesa = R100_CONTEXT(ctx);
418 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
419 GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
421 s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;
422 t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK);
424 if ( ctx->Polygon.CullFlag ) {
425 switch ( ctx->Polygon.CullFaceMode ) {
427 s &= ~RADEON_FFACE_SOLID;
428 t |= RADEON_CULL_FRONT;
431 s &= ~RADEON_BFACE_SOLID;
432 t |= RADEON_CULL_BACK;
434 case GL_FRONT_AND_BACK:
435 s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);
436 t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK);
441 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
442 RADEON_STATECHANGE(rmesa, set );
443 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
446 if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
447 RADEON_STATECHANGE(rmesa, tcl );
448 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
452 static void radeonFrontFace( struct gl_context *ctx, GLenum mode )
454 r100ContextPtr rmesa = R100_CONTEXT(ctx);
456 RADEON_STATECHANGE( rmesa, set );
457 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK;
459 RADEON_STATECHANGE( rmesa, tcl );
460 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;
462 /* Winding is inverted when rendering to FBO */
463 if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
464 mode = (mode == GL_CW) ? GL_CCW : GL_CW;
468 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW;
471 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CCW;
472 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW;
478 /* =============================================================
481 static void radeonLineWidth( struct gl_context *ctx, GLfloat widthf )
483 r100ContextPtr rmesa = R100_CONTEXT(ctx);
485 RADEON_STATECHANGE( rmesa, lin );
486 RADEON_STATECHANGE( rmesa, set );
488 /* Line width is stored in U6.4 format.
490 rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0);
491 if ( widthf > 1.0 ) {
492 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_WIDELINE_ENABLE;
494 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE;
498 static void radeonLineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
500 r100ContextPtr rmesa = R100_CONTEXT(ctx);
502 RADEON_STATECHANGE( rmesa, lin );
503 rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
504 ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
508 /* =============================================================
511 static void radeonColorMask( struct gl_context *ctx,
512 GLboolean r, GLboolean g,
513 GLboolean b, GLboolean a )
515 r100ContextPtr rmesa = R100_CONTEXT(ctx);
516 struct radeon_renderbuffer *rrb;
519 rrb = radeon_get_colorbuffer(&rmesa->radeon);
523 mask = radeonPackColor( rrb->cpp,
524 ctx->Color.ColorMask[0][RCOMP],
525 ctx->Color.ColorMask[0][GCOMP],
526 ctx->Color.ColorMask[0][BCOMP],
527 ctx->Color.ColorMask[0][ACOMP] );
529 if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
530 RADEON_STATECHANGE( rmesa, msk );
531 rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
536 /* =============================================================
540 static void radeonPolygonOffset( struct gl_context *ctx,
541 GLfloat factor, GLfloat units )
543 r100ContextPtr rmesa = R100_CONTEXT(ctx);
544 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
545 float_ui32_type constant = { units * depthScale };
546 float_ui32_type factoru = { factor };
548 RADEON_STATECHANGE( rmesa, zbs );
549 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = factoru.ui32;
550 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
553 static void radeonPolygonStipplePreKMS( struct gl_context *ctx, const GLubyte *mask )
555 r100ContextPtr rmesa = R100_CONTEXT(ctx);
557 drm_radeon_stipple_t stipple;
559 /* Must flip pattern upside down.
561 for ( i = 0 ; i < 32 ; i++ ) {
562 rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i];
565 /* TODO: push this into cmd mechanism
567 radeon_firevertices(&rmesa->radeon);
568 LOCK_HARDWARE( &rmesa->radeon );
570 /* FIXME: Use window x,y offsets into stipple RAM.
572 stipple.mask = rmesa->state.stipple.mask;
573 drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE,
574 &stipple, sizeof(drm_radeon_stipple_t) );
575 UNLOCK_HARDWARE( &rmesa->radeon );
578 static void radeonPolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
580 r100ContextPtr rmesa = R100_CONTEXT(ctx);
581 GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
583 /* Can't generally do unfilled via tcl, but some good special
586 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag);
587 if (rmesa->radeon.TclFallback) {
588 radeonChooseRenderState( ctx );
589 radeonChooseVertexState( ctx );
594 /* =============================================================
595 * Rendering attributes
597 * We really don't want to recalculate all this every time we bind a
598 * texture. These things shouldn't change all that often, so it makes
599 * sense to break them out of the core texture state update routines.
602 /* Examine lighting and texture state to determine if separate specular
605 static void radeonUpdateSpecular( struct gl_context *ctx )
607 r100ContextPtr rmesa = R100_CONTEXT(ctx);
608 uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
611 RADEON_STATECHANGE( rmesa, tcl );
613 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
614 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
615 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
616 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE;
617 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
619 p &= ~RADEON_SPECULAR_ENABLE;
621 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE;
624 if (ctx->Light.Enabled &&
625 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
626 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
627 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
628 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
629 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
630 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
631 p |= RADEON_SPECULAR_ENABLE;
632 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
633 ~RADEON_DIFFUSE_SPECULAR_COMBINE;
635 else if (ctx->Light.Enabled) {
636 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
637 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
638 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
639 } else if (ctx->Fog.ColorSumEnabled ) {
640 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
641 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
642 p |= RADEON_SPECULAR_ENABLE;
644 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
647 if (ctx->Fog.Enabled) {
648 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
649 if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
650 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
651 /* Bizzare: have to leave lighting enabled to get fog. */
652 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
655 /* cannot do tcl fog factor calculation with fog coord source
656 * (send precomputed factors). Cannot use precomputed fog
657 * factors together with tcl spec light (need tcl fallback) */
658 flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
659 RADEON_TCL_COMPUTE_SPECULAR) != 0;
663 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
665 if (_mesa_need_secondary_color(ctx)) {
666 assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
668 assert( (p & RADEON_SPECULAR_ENABLE) == 0 );
671 if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
672 RADEON_STATECHANGE( rmesa, ctx );
673 rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
676 /* Update vertex/render formats
678 if (rmesa->radeon.TclFallback) {
679 radeonChooseRenderState( ctx );
680 radeonChooseVertexState( ctx );
685 /* =============================================================
690 /* Update on colormaterial, material emmissive/ambient,
691 * lightmodel.globalambient
693 static void update_global_ambient( struct gl_context *ctx )
695 r100ContextPtr rmesa = R100_CONTEXT(ctx);
696 float *fcmd = (float *)RADEON_DB_STATE( glt );
698 /* Need to do more if both emmissive & ambient are PREMULT:
699 * Hope this is not needed for MULT
701 if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
702 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
703 (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
705 COPY_3V( &fcmd[GLT_RED],
706 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
707 ACC_SCALE_3V( &fcmd[GLT_RED],
708 ctx->Light.Model.Ambient,
709 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
713 COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
716 RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
719 /* Update on change to
723 static void update_light_colors( struct gl_context *ctx, GLuint p )
725 struct gl_light *l = &ctx->Light.Light[p];
727 /* fprintf(stderr, "%s\n", __FUNCTION__); */
730 r100ContextPtr rmesa = R100_CONTEXT(ctx);
731 float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
733 COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
734 COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
735 COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
737 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
741 /* Also fallback for asym colormaterial mode in twoside lighting...
743 static void check_twoside_fallback( struct gl_context *ctx )
745 GLboolean fallback = GL_FALSE;
748 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
749 if (ctx->Light.ColorMaterialEnabled &&
750 (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
751 ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
754 for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
755 if (memcmp( ctx->Light.Material.Attrib[i],
756 ctx->Light.Material.Attrib[i+1],
757 sizeof(GLfloat)*4) != 0) {
764 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
768 static void radeonColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
770 r100ContextPtr rmesa = R100_CONTEXT(ctx);
771 GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
773 light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
774 (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
775 (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
776 (3 << RADEON_SPECULAR_SOURCE_SHIFT));
778 if (ctx->Light.ColorMaterialEnabled) {
779 GLuint mask = ctx->Light.ColorMaterialBitmask;
781 if (mask & MAT_BIT_FRONT_EMISSION) {
782 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
783 RADEON_EMISSIVE_SOURCE_SHIFT);
786 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
787 RADEON_EMISSIVE_SOURCE_SHIFT);
790 if (mask & MAT_BIT_FRONT_AMBIENT) {
791 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
792 RADEON_AMBIENT_SOURCE_SHIFT);
795 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
796 RADEON_AMBIENT_SOURCE_SHIFT);
799 if (mask & MAT_BIT_FRONT_DIFFUSE) {
800 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
801 RADEON_DIFFUSE_SOURCE_SHIFT);
804 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
805 RADEON_DIFFUSE_SOURCE_SHIFT);
808 if (mask & MAT_BIT_FRONT_SPECULAR) {
809 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
810 RADEON_SPECULAR_SOURCE_SHIFT);
813 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
814 RADEON_SPECULAR_SOURCE_SHIFT);
820 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
821 (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
822 (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
823 (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
826 if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
827 RADEON_STATECHANGE( rmesa, tcl );
828 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
832 void radeonUpdateMaterial( struct gl_context *ctx )
834 r100ContextPtr rmesa = R100_CONTEXT(ctx);
835 GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
836 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
839 if (ctx->Light.ColorMaterialEnabled)
840 mask &= ~ctx->Light.ColorMaterialBitmask;
842 if (RADEON_DEBUG & RADEON_STATE)
843 fprintf(stderr, "%s\n", __FUNCTION__);
846 if (mask & MAT_BIT_FRONT_EMISSION) {
847 fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0];
848 fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
849 fcmd[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_FRONT_EMISSION][2];
850 fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
852 if (mask & MAT_BIT_FRONT_AMBIENT) {
853 fcmd[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
854 fcmd[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
855 fcmd[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
856 fcmd[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
858 if (mask & MAT_BIT_FRONT_DIFFUSE) {
859 fcmd[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
860 fcmd[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
861 fcmd[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
862 fcmd[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
864 if (mask & MAT_BIT_FRONT_SPECULAR) {
865 fcmd[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
866 fcmd[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
867 fcmd[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
868 fcmd[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
870 if (mask & MAT_BIT_FRONT_SHININESS) {
871 fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0];
874 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl );
876 check_twoside_fallback( ctx );
877 /* update_global_ambient( ctx );*/
882 * _MESA_NEW_NEED_EYE_COORDS
884 * Uses derived state from mesa:
893 * which are calculated in light.c and are correct for the current
894 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
895 * and _MESA_NEW_NEED_EYE_COORDS.
897 static void update_light( struct gl_context *ctx )
899 r100ContextPtr rmesa = R100_CONTEXT(ctx);
901 /* Have to check these, or have an automatic shortcircuit mechanism
902 * to remove noop statechanges. (Or just do a better job on the
906 GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
908 if (ctx->_NeedEyeCoords)
909 tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
911 tmp |= RADEON_LIGHT_IN_MODELSPACE;
914 /* Leave this test disabled: (unexplained q3 lockup) (even with
917 if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
919 RADEON_STATECHANGE( rmesa, tcl );
920 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
925 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
926 fcmd[EYE_X] = ctx->_EyeZDir[0];
927 fcmd[EYE_Y] = ctx->_EyeZDir[1];
928 fcmd[EYE_Z] = - ctx->_EyeZDir[2];
929 fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
930 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
935 if (ctx->Light.Enabled) {
937 for (p = 0 ; p < MAX_LIGHTS; p++) {
938 if (ctx->Light.Light[p].Enabled) {
939 struct gl_light *l = &ctx->Light.Light[p];
940 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
942 if (l->EyePosition[3] == 0.0) {
943 COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
944 COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
945 fcmd[LIT_POSITION_W] = 0;
946 fcmd[LIT_DIRECTION_W] = 0;
948 COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
949 fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
950 fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
951 fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
952 fcmd[LIT_DIRECTION_W] = 0;
955 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
961 static void radeonLightfv( struct gl_context *ctx, GLenum light,
962 GLenum pname, const GLfloat *params )
964 r100ContextPtr rmesa = R100_CONTEXT(ctx);
965 GLint p = light - GL_LIGHT0;
966 struct gl_light *l = &ctx->Light.Light[p];
967 GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
974 update_light_colors( ctx, p );
977 case GL_SPOT_DIRECTION:
978 /* picked up in update_light */
982 /* positions picked up in update_light, but can do flag here */
984 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
986 /* FIXME: Set RANGE_ATTEN only when needed */
988 flag = RADEON_LIGHT_1_IS_LOCAL;
990 flag = RADEON_LIGHT_0_IS_LOCAL;
992 RADEON_STATECHANGE(rmesa, tcl);
993 if (l->EyePosition[3] != 0.0F)
994 rmesa->hw.tcl.cmd[idx] |= flag;
996 rmesa->hw.tcl.cmd[idx] &= ~flag;
1000 case GL_SPOT_EXPONENT:
1001 RADEON_STATECHANGE(rmesa, lit[p]);
1002 fcmd[LIT_SPOT_EXPONENT] = params[0];
1005 case GL_SPOT_CUTOFF: {
1006 GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
1007 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1009 RADEON_STATECHANGE(rmesa, lit[p]);
1010 fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
1012 RADEON_STATECHANGE(rmesa, tcl);
1013 if (l->SpotCutoff != 180.0F)
1014 rmesa->hw.tcl.cmd[idx] |= flag;
1016 rmesa->hw.tcl.cmd[idx] &= ~flag;
1021 case GL_CONSTANT_ATTENUATION:
1022 RADEON_STATECHANGE(rmesa, lit[p]);
1023 fcmd[LIT_ATTEN_CONST] = params[0];
1024 if ( params[0] == 0.0 )
1025 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
1027 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
1029 case GL_LINEAR_ATTENUATION:
1030 RADEON_STATECHANGE(rmesa, lit[p]);
1031 fcmd[LIT_ATTEN_LINEAR] = params[0];
1033 case GL_QUADRATIC_ATTENUATION:
1034 RADEON_STATECHANGE(rmesa, lit[p]);
1035 fcmd[LIT_ATTEN_QUADRATIC] = params[0];
1041 /* Set RANGE_ATTEN only when needed */
1044 case GL_CONSTANT_ATTENUATION:
1045 case GL_LINEAR_ATTENUATION:
1046 case GL_QUADRATIC_ATTENUATION:
1048 GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
1049 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1050 GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1051 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
1052 GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1053 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
1055 if ( l->EyePosition[3] == 0.0F ||
1056 ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1057 fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1058 /* Disable attenuation */
1059 icmd[idx] &= ~atten_flag;
1061 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1062 /* Enable only constant portion of attenuation calculation */
1063 icmd[idx] |= ( atten_flag | atten_const_flag );
1065 /* Enable full attenuation calculation */
1066 icmd[idx] &= ~atten_const_flag;
1067 icmd[idx] |= atten_flag;
1071 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1082 static void radeonLightModelfv( struct gl_context *ctx, GLenum pname,
1083 const GLfloat *param )
1085 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1088 case GL_LIGHT_MODEL_AMBIENT:
1089 update_global_ambient( ctx );
1092 case GL_LIGHT_MODEL_LOCAL_VIEWER:
1093 RADEON_STATECHANGE( rmesa, tcl );
1094 if (ctx->Light.Model.LocalViewer)
1095 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
1097 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
1100 case GL_LIGHT_MODEL_TWO_SIDE:
1101 RADEON_STATECHANGE( rmesa, tcl );
1102 if (ctx->Light.Model.TwoSide)
1103 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
1105 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
1107 check_twoside_fallback( ctx );
1109 if (rmesa->radeon.TclFallback) {
1110 radeonChooseRenderState( ctx );
1111 radeonChooseVertexState( ctx );
1115 case GL_LIGHT_MODEL_COLOR_CONTROL:
1116 radeonUpdateSpecular(ctx);
1124 static void radeonShadeModel( struct gl_context *ctx, GLenum mode )
1126 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1127 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1129 s &= ~(RADEON_DIFFUSE_SHADE_MASK |
1130 RADEON_ALPHA_SHADE_MASK |
1131 RADEON_SPECULAR_SHADE_MASK |
1132 RADEON_FOG_SHADE_MASK);
1136 s |= (RADEON_DIFFUSE_SHADE_FLAT |
1137 RADEON_ALPHA_SHADE_FLAT |
1138 RADEON_SPECULAR_SHADE_FLAT |
1139 RADEON_FOG_SHADE_FLAT);
1142 s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
1143 RADEON_ALPHA_SHADE_GOURAUD |
1144 RADEON_SPECULAR_SHADE_GOURAUD |
1145 RADEON_FOG_SHADE_GOURAUD);
1151 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1152 RADEON_STATECHANGE( rmesa, set );
1153 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1158 /* =============================================================
1162 static void radeonClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1164 GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1165 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1166 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1168 RADEON_STATECHANGE( rmesa, ucp[p] );
1169 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1170 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1171 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1172 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1175 static void radeonUpdateClipPlanes( struct gl_context *ctx )
1177 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1180 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1181 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1182 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1184 RADEON_STATECHANGE( rmesa, ucp[p] );
1185 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1186 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1187 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1188 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1194 /* =============================================================
1199 radeonStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1200 GLint ref, GLuint mask )
1202 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1203 GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) |
1204 ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
1206 RADEON_STATECHANGE( rmesa, ctx );
1207 RADEON_STATECHANGE( rmesa, msk );
1209 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
1210 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
1211 RADEON_STENCIL_VALUE_MASK);
1213 switch ( ctx->Stencil.Function[0] ) {
1215 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
1218 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
1221 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
1224 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
1227 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
1230 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
1233 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
1236 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
1240 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1244 radeonStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1246 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1248 RADEON_STATECHANGE( rmesa, msk );
1249 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
1250 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1251 ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
1254 static void radeonStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1255 GLenum zfail, GLenum zpass )
1257 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1259 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1260 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1261 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1263 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
1264 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
1265 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1266 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1267 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1268 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
1270 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
1271 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
1272 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
1273 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
1274 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
1275 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
1276 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
1279 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
1280 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
1281 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
1282 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
1283 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
1284 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
1287 RADEON_STATECHANGE( rmesa, ctx );
1288 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1289 RADEON_STENCIL_ZFAIL_MASK |
1290 RADEON_STENCIL_ZPASS_MASK);
1292 switch ( ctx->Stencil.FailFunc[0] ) {
1294 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1297 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1300 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1303 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1306 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1309 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
1312 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
1315 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1319 switch ( ctx->Stencil.ZFailFunc[0] ) {
1321 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1324 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1327 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1330 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1333 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1336 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1339 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1342 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1346 switch ( ctx->Stencil.ZPassFunc[0] ) {
1348 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1351 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1354 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1357 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1360 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1363 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
1366 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1369 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1374 static void radeonClearStencil( struct gl_context *ctx, GLint s )
1376 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1378 rmesa->radeon.state.stencil.clear =
1379 ((GLuint) (ctx->Stencil.Clear & 0xff) |
1380 (0xff << RADEON_STENCIL_MASK_SHIFT) |
1381 ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT));
1385 /* =============================================================
1386 * Window position and viewport transformation
1390 * To correctly position primitives:
1392 #define SUBPIXEL_X 0.125
1393 #define SUBPIXEL_Y 0.125
1397 * Called when window size or position changes or viewport or depth range
1398 * state is changed. We update the hardware viewport state here.
1400 void radeonUpdateWindow( struct gl_context *ctx )
1402 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1403 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1404 GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
1405 GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
1406 const GLfloat *v = ctx->Viewport._WindowMap.m;
1407 const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
1408 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1409 GLfloat y_scale, y_bias;
1411 if (render_to_fbo) {
1419 float_ui32_type sx = { v[MAT_SX] };
1420 float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
1421 float_ui32_type sy = { v[MAT_SY] * y_scale };
1422 float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
1423 float_ui32_type sz = { v[MAT_SZ] * depthScale };
1424 float_ui32_type tz = { v[MAT_TZ] * depthScale };
1426 RADEON_STATECHANGE( rmesa, vpt );
1428 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32;
1429 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1430 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32;
1431 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1432 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32;
1433 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1437 static void radeonViewport( struct gl_context *ctx, GLint x, GLint y,
1438 GLsizei width, GLsizei height )
1440 /* Don't pipeline viewport changes, conflict with window offset
1441 * setting below. Could apply deltas to rescue pipelined viewport
1442 * values, or keep the originals hanging around.
1444 radeonUpdateWindow( ctx );
1446 radeon_viewport(ctx, x, y, width, height);
1449 static void radeonDepthRange( struct gl_context *ctx, GLclampd nearval,
1452 radeonUpdateWindow( ctx );
1455 void radeonUpdateViewportOffset( struct gl_context *ctx )
1457 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1458 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1459 GLfloat xoffset = (GLfloat)dPriv->x;
1460 GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1461 const GLfloat *v = ctx->Viewport._WindowMap.m;
1466 tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X;
1467 ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1469 if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
1470 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
1472 /* Note: this should also modify whatever data the context reset
1475 RADEON_STATECHANGE( rmesa, vpt );
1476 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1477 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1479 /* update polygon stipple x/y screen offset */
1482 GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1484 m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
1485 RADEON_STIPPLE_Y_OFFSET_MASK);
1487 /* add magic offsets, then invert */
1488 stx = 31 - ((dPriv->x - 1) & RADEON_STIPPLE_COORD_MASK);
1489 sty = 31 - ((dPriv->y + dPriv->h - 1)
1490 & RADEON_STIPPLE_COORD_MASK);
1492 m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
1493 (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
1495 if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1496 RADEON_STATECHANGE( rmesa, msc );
1497 rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1502 radeonUpdateScissor( ctx );
1507 /* =============================================================
1511 static void radeonClearColor( struct gl_context *ctx,
1512 const union gl_color_union color )
1514 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1516 struct radeon_renderbuffer *rrb;
1518 rrb = radeon_get_colorbuffer(&rmesa->radeon);
1522 UNCLAMPED_FLOAT_TO_UBYTE(c[0], color.f[0]);
1523 UNCLAMPED_FLOAT_TO_UBYTE(c[1], color.f[1]);
1524 UNCLAMPED_FLOAT_TO_UBYTE(c[2], color.f[2]);
1525 UNCLAMPED_FLOAT_TO_UBYTE(c[3], color.f[3]);
1526 rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
1527 c[0], c[1], c[2], c[3] );
1531 static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
1533 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1534 FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1538 static GLuint radeon_rop_tab[] = {
1541 RADEON_ROP_AND_REVERSE,
1543 RADEON_ROP_AND_INVERTED,
1550 RADEON_ROP_OR_REVERSE,
1551 RADEON_ROP_COPY_INVERTED,
1552 RADEON_ROP_OR_INVERTED,
1557 static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode )
1559 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1560 GLuint rop = (GLuint)opcode - GL_CLEAR;
1564 RADEON_STATECHANGE( rmesa, msk );
1565 rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1568 /* =============================================================
1569 * State enable/disable
1572 static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
1574 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1577 if ( RADEON_DEBUG & RADEON_STATE )
1578 fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1579 _mesa_lookup_enum_by_nr( cap ),
1580 state ? "GL_TRUE" : "GL_FALSE" );
1583 /* Fast track this one...
1591 RADEON_STATECHANGE( rmesa, ctx );
1593 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1595 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1600 RADEON_STATECHANGE( rmesa, ctx );
1602 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE;
1604 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1606 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1607 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1608 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1610 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1613 /* Catch a possible fallback:
1616 ctx->Driver.BlendEquationSeparate( ctx,
1617 ctx->Color.Blend[0].EquationRGB,
1618 ctx->Color.Blend[0].EquationA );
1619 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
1620 ctx->Color.Blend[0].DstRGB,
1621 ctx->Color.Blend[0].SrcA,
1622 ctx->Color.Blend[0].DstA );
1625 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1626 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1630 case GL_CLIP_PLANE0:
1631 case GL_CLIP_PLANE1:
1632 case GL_CLIP_PLANE2:
1633 case GL_CLIP_PLANE3:
1634 case GL_CLIP_PLANE4:
1635 case GL_CLIP_PLANE5:
1636 p = cap-GL_CLIP_PLANE0;
1637 RADEON_STATECHANGE( rmesa, tcl );
1639 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1640 radeonClipPlane( ctx, cap, NULL );
1643 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1647 case GL_COLOR_MATERIAL:
1648 radeonColorMaterial( ctx, 0, 0 );
1649 radeonUpdateMaterial( ctx );
1653 radeonCullFace( ctx, 0 );
1657 RADEON_STATECHANGE(rmesa, ctx );
1659 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE;
1661 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1666 RADEON_STATECHANGE(rmesa, ctx );
1668 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE;
1669 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1671 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1672 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable;
1677 RADEON_STATECHANGE(rmesa, ctx );
1679 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1680 radeonFogfv( ctx, GL_FOG_MODE, NULL );
1682 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1683 RADEON_STATECHANGE(rmesa, tcl);
1684 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1686 radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1687 _mesa_allow_light_in_model( ctx, !state );
1698 RADEON_STATECHANGE(rmesa, tcl);
1699 p = cap - GL_LIGHT0;
1701 flag = (RADEON_LIGHT_1_ENABLE |
1702 RADEON_LIGHT_1_ENABLE_AMBIENT |
1703 RADEON_LIGHT_1_ENABLE_SPECULAR);
1705 flag = (RADEON_LIGHT_0_ENABLE |
1706 RADEON_LIGHT_0_ENABLE_AMBIENT |
1707 RADEON_LIGHT_0_ENABLE_SPECULAR);
1710 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1712 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1716 update_light_colors( ctx, p );
1720 RADEON_STATECHANGE(rmesa, tcl);
1721 radeonUpdateSpecular(ctx);
1722 check_twoside_fallback( ctx );
1725 case GL_LINE_SMOOTH:
1726 RADEON_STATECHANGE( rmesa, ctx );
1728 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE;
1730 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1734 case GL_LINE_STIPPLE:
1735 RADEON_STATECHANGE( rmesa, ctx );
1737 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE;
1739 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1743 case GL_COLOR_LOGIC_OP:
1744 RADEON_STATECHANGE( rmesa, ctx );
1745 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1746 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1747 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1749 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1754 RADEON_STATECHANGE( rmesa, tcl );
1756 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS;
1758 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1762 case GL_POLYGON_OFFSET_POINT:
1763 RADEON_STATECHANGE( rmesa, set );
1765 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
1767 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1771 case GL_POLYGON_OFFSET_LINE:
1772 RADEON_STATECHANGE( rmesa, set );
1774 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
1776 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1780 case GL_POLYGON_OFFSET_FILL:
1781 RADEON_STATECHANGE( rmesa, set );
1783 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
1785 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1789 case GL_POLYGON_SMOOTH:
1790 RADEON_STATECHANGE( rmesa, ctx );
1792 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY;
1794 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1798 case GL_POLYGON_STIPPLE:
1799 RADEON_STATECHANGE(rmesa, ctx );
1801 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE;
1803 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1807 case GL_RESCALE_NORMAL_EXT: {
1808 GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1809 RADEON_STATECHANGE( rmesa, tcl );
1811 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1813 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1818 case GL_SCISSOR_TEST:
1819 radeon_firevertices(&rmesa->radeon);
1820 rmesa->radeon.state.scissor.enabled = state;
1821 radeonUpdateScissor( ctx );
1824 case GL_STENCIL_TEST:
1826 GLboolean hw_stencil = GL_FALSE;
1827 if (ctx->DrawBuffer) {
1828 struct radeon_renderbuffer *rrbStencil
1829 = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1830 hw_stencil = (rrbStencil && rrbStencil->bo);
1834 RADEON_STATECHANGE( rmesa, ctx );
1836 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE;
1838 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1841 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1846 case GL_TEXTURE_GEN_Q:
1847 case GL_TEXTURE_GEN_R:
1848 case GL_TEXTURE_GEN_S:
1849 case GL_TEXTURE_GEN_T:
1850 /* Picked up in radeonUpdateTextureState.
1852 rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1855 case GL_COLOR_SUM_EXT:
1856 radeonUpdateSpecular ( ctx );
1865 static void radeonLightingSpaceChange( struct gl_context *ctx )
1867 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1869 RADEON_STATECHANGE( rmesa, tcl );
1871 if (RADEON_DEBUG & RADEON_STATE)
1872 fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1873 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1875 if (ctx->_NeedEyeCoords)
1876 tmp = ctx->Transform.RescaleNormals;
1878 tmp = !ctx->Transform.RescaleNormals;
1881 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1883 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1886 if (RADEON_DEBUG & RADEON_STATE)
1887 fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1888 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1891 /* =============================================================
1892 * Deferred state management - matrices, textures, other?
1896 void radeonUploadTexMatrix( r100ContextPtr rmesa,
1897 int unit, GLboolean swapcols )
1899 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1900 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1901 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1902 texgen generates all 4 coords, at least tests with projtex indicated that.
1903 So: if we need the q coord in the end (solely determined by the texture
1904 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1905 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1906 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1907 will get submitted in the "wrong", i.e. 3rd, slot.
1908 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1909 size and using the texture matrix to swap the r and q coords around (ut2k3
1910 does exactly that), so we don't need the 3rd / 4th column swap - still need
1911 the 3rd / 4th row swap of course. This will potentially break for apps which
1912 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1913 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1914 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1915 incredibly hard to detect so we can't just fallback in such a case. Assume
1916 it never happens... - rs
1919 int idx = TEXMAT_0 + unit;
1920 float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1922 struct gl_texture_unit tUnit = rmesa->radeon.glCtx->Texture.Unit[unit];
1923 GLfloat *src = rmesa->tmpmat[unit].m;
1925 rmesa->TexMatColSwap &= ~(1 << unit);
1926 if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
1928 rmesa->TexMatColSwap |= 1 << unit;
1929 /* attention some elems are swapped 2 times! */
1942 /* those last 4 are probably never used */
1949 for (i = 0; i < 2; i++) {
1953 *dest++ = src[i+12];
1955 for (i = 3; i >= 2; i--) {
1959 *dest++ = src[i+12];
1964 for (i = 0 ; i < 4 ; i++) {
1968 *dest++ = src[i+12];
1972 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1976 static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1978 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1982 for (i = 0 ; i < 4 ; i++) {
1986 *dest++ = src[i+12];
1989 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1992 static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1994 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1995 memcpy(dest, src, 16*sizeof(float));
1996 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2000 static void update_texturematrix( struct gl_context *ctx )
2002 r100ContextPtr rmesa = R100_CONTEXT( ctx );
2003 GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
2004 GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
2006 GLuint texMatEnabled = 0;
2007 rmesa->NeedTexMatrix = 0;
2008 rmesa->TexMatColSwap = 0;
2010 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
2011 if (ctx->Texture.Unit[unit]._ReallyEnabled) {
2012 GLboolean needMatrix = GL_FALSE;
2013 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2014 needMatrix = GL_TRUE;
2015 texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
2016 RADEON_TEXMAT_0_ENABLE) << unit;
2018 if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2019 /* Need to preconcatenate any active texgen
2020 * obj/eyeplane matrices:
2022 _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
2023 ctx->TextureMatrixStack[unit].Top,
2024 &rmesa->TexGenMatrix[unit] );
2027 _math_matrix_copy( &rmesa->tmpmat[unit],
2028 ctx->TextureMatrixStack[unit].Top );
2031 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2032 _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
2033 needMatrix = GL_TRUE;
2036 rmesa->NeedTexMatrix |= 1 << unit;
2037 radeonUploadTexMatrix( rmesa, unit,
2038 !ctx->Texture.Unit[unit].TexGenEnabled );
2043 tpc = (texMatEnabled | rmesa->TexGenEnabled);
2045 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2046 vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
2047 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
2048 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
2050 vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
2051 (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
2052 ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
2053 (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
2054 ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
2055 (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
2057 if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
2058 vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
2060 RADEON_STATECHANGE(rmesa, tcl);
2061 rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
2062 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
2066 static GLboolean r100ValidateBuffers(struct gl_context *ctx)
2068 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2069 struct radeon_renderbuffer *rrb;
2072 radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2074 rrb = radeon_get_colorbuffer(&rmesa->radeon);
2076 if (rrb && rrb->bo) {
2077 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2078 0, RADEON_GEM_DOMAIN_VRAM);
2082 rrb = radeon_get_depthbuffer(&rmesa->radeon);
2084 if (rrb && rrb->bo) {
2085 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2086 0, RADEON_GEM_DOMAIN_VRAM);
2089 for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
2092 if (!ctx->Texture.Unit[i]._ReallyEnabled)
2095 t = rmesa->state.texture.unit[i].texobj;
2099 if (t->image_override && t->bo)
2100 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2101 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2103 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2104 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2107 ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
2113 GLboolean radeonValidateState( struct gl_context *ctx )
2115 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2116 GLuint new_state = rmesa->radeon.NewGLState;
2118 if (new_state & _NEW_BUFFERS) {
2119 _mesa_update_framebuffer(ctx);
2120 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2121 _mesa_update_draw_buffer_bounds(ctx);
2122 RADEON_STATECHANGE(rmesa, ctx);
2125 if (new_state & _NEW_TEXTURE) {
2126 radeonUpdateTextureState( ctx );
2127 new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2130 /* we need to do a space check here */
2131 if (!r100ValidateBuffers(ctx))
2134 /* Need an event driven matrix update?
2136 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2137 upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2139 /* Need these for lighting (shouldn't upload otherwise)
2141 if (new_state & (_NEW_MODELVIEW)) {
2142 upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2143 upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2146 /* Does this need to be triggered on eg. modelview for
2147 * texgen-derived objplane/eyeplane matrices?
2149 if (new_state & _NEW_TEXTURE_MATRIX) {
2150 update_texturematrix( ctx );
2153 if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2154 update_light( ctx );
2157 /* emit all active clip planes if projection matrix changes.
2159 if (new_state & (_NEW_PROJECTION)) {
2160 if (ctx->Transform.ClipPlanesEnabled)
2161 radeonUpdateClipPlanes( ctx );
2165 rmesa->radeon.NewGLState = 0;
2171 static void radeonInvalidateState( struct gl_context *ctx, GLuint new_state )
2173 _swrast_InvalidateState( ctx, new_state );
2174 _swsetup_InvalidateState( ctx, new_state );
2175 _vbo_InvalidateState( ctx, new_state );
2176 _tnl_InvalidateState( ctx, new_state );
2177 _ae_invalidate_state( ctx, new_state );
2178 R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2182 /* A hack. Need a faster way to find this out.
2184 static GLboolean check_material( struct gl_context *ctx )
2186 TNLcontext *tnl = TNL_CONTEXT(ctx);
2189 for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2190 i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2192 if (tnl->vb.AttribPtr[i] &&
2193 tnl->vb.AttribPtr[i]->stride)
2200 static void radeonWrapRunPipeline( struct gl_context *ctx )
2202 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2203 GLboolean has_material;
2206 fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2210 if (rmesa->radeon.NewGLState)
2211 if (!radeonValidateState( ctx ))
2212 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2214 has_material = (ctx->Light.Enabled && check_material( ctx ));
2217 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2220 /* Run the pipeline.
2222 _tnl_run_pipeline( ctx );
2225 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2229 static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2231 r100ContextPtr r100 = R100_CONTEXT(ctx);
2234 radeon_firevertices(&r100->radeon);
2236 RADEON_STATECHANGE(r100, stp);
2238 /* Must flip pattern upside down.
2240 for ( i = 31 ; i >= 0; i--) {
2241 r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2246 /* Initialize the driver's state functions.
2247 * Many of the ctx->Driver functions might have been initialized to
2248 * software defaults in the earlier _mesa_init_driver_functions() call.
2250 void radeonInitStateFuncs( struct gl_context *ctx , GLboolean dri2 )
2252 ctx->Driver.UpdateState = radeonInvalidateState;
2253 ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
2255 ctx->Driver.DrawBuffer = radeonDrawBuffer;
2256 ctx->Driver.ReadBuffer = radeonReadBuffer;
2257 ctx->Driver.CopyPixels = _mesa_meta_CopyPixels;
2258 ctx->Driver.DrawPixels = _mesa_meta_DrawPixels;
2260 ctx->Driver.ReadPixels = radeonReadPixels;
2262 ctx->Driver.AlphaFunc = radeonAlphaFunc;
2263 ctx->Driver.BlendEquationSeparate = radeonBlendEquationSeparate;
2264 ctx->Driver.BlendFuncSeparate = radeonBlendFuncSeparate;
2265 ctx->Driver.ClearColor = radeonClearColor;
2266 ctx->Driver.ClearDepth = radeonClearDepth;
2267 ctx->Driver.ClearStencil = radeonClearStencil;
2268 ctx->Driver.ClipPlane = radeonClipPlane;
2269 ctx->Driver.ColorMask = radeonColorMask;
2270 ctx->Driver.CullFace = radeonCullFace;
2271 ctx->Driver.DepthFunc = radeonDepthFunc;
2272 ctx->Driver.DepthMask = radeonDepthMask;
2273 ctx->Driver.DepthRange = radeonDepthRange;
2274 ctx->Driver.Enable = radeonEnable;
2275 ctx->Driver.Fogfv = radeonFogfv;
2276 ctx->Driver.FrontFace = radeonFrontFace;
2277 ctx->Driver.Hint = NULL;
2278 ctx->Driver.LightModelfv = radeonLightModelfv;
2279 ctx->Driver.Lightfv = radeonLightfv;
2280 ctx->Driver.LineStipple = radeonLineStipple;
2281 ctx->Driver.LineWidth = radeonLineWidth;
2282 ctx->Driver.LogicOpcode = radeonLogicOpCode;
2283 ctx->Driver.PolygonMode = radeonPolygonMode;
2284 ctx->Driver.PolygonOffset = radeonPolygonOffset;
2286 ctx->Driver.PolygonStipple = radeonPolygonStipple;
2288 ctx->Driver.PolygonStipple = radeonPolygonStipplePreKMS;
2289 ctx->Driver.RenderMode = radeonRenderMode;
2290 ctx->Driver.Scissor = radeonScissor;
2291 ctx->Driver.ShadeModel = radeonShadeModel;
2292 ctx->Driver.StencilFuncSeparate = radeonStencilFuncSeparate;
2293 ctx->Driver.StencilMaskSeparate = radeonStencilMaskSeparate;
2294 ctx->Driver.StencilOpSeparate = radeonStencilOpSeparate;
2295 ctx->Driver.Viewport = radeonViewport;
2297 TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2298 TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;