radeon_state.c revision 6c48c93a5358ab04d6779afb14203bd1680a37a0
1/**************************************************************************
2
3Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
4
5All Rights Reserved.
6
7Permission is hereby granted, free of charge, to any person obtaining
8a copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sublicense, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice (including the
16next paragraph) shall be included in all copies or substantial
17portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27**************************************************************************/
28
29/*
30 * Authors:
31 *   Gareth Hughes <gareth@valinux.com>
32 *   Keith Whitwell <keith@tungstengraphics.com>
33 */
34
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/state.h"
41#include "main/context.h"
42#include "main/framebuffer.h"
43
44#include "vbo/vbo.h"
45#include "tnl/tnl.h"
46#include "tnl/t_pipeline.h"
47#include "swrast_setup/swrast_setup.h"
48
49#include "radeon_context.h"
50#include "radeon_ioctl.h"
51#include "radeon_state.h"
52#include "radeon_tcl.h"
53#include "radeon_tex.h"
54#include "radeon_swtcl.h"
55#include "drirenderbuffer.h"
56
57static void radeonUpdateSpecular( GLcontext *ctx );
58
59/* =============================================================
60 * Alpha blending
61 */
62
63static void radeonAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
64{
65   r100ContextPtr rmesa = R100_CONTEXT(ctx);
66   int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC];
67   GLubyte refByte;
68
69   CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
70
71   RADEON_STATECHANGE( rmesa, ctx );
72
73   pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK);
74   pp_misc |= (refByte & RADEON_REF_ALPHA_MASK);
75
76   switch ( func ) {
77   case GL_NEVER:
78      pp_misc |= RADEON_ALPHA_TEST_FAIL;
79      break;
80   case GL_LESS:
81      pp_misc |= RADEON_ALPHA_TEST_LESS;
82      break;
83   case GL_EQUAL:
84      pp_misc |= RADEON_ALPHA_TEST_EQUAL;
85      break;
86   case GL_LEQUAL:
87      pp_misc |= RADEON_ALPHA_TEST_LEQUAL;
88      break;
89   case GL_GREATER:
90      pp_misc |= RADEON_ALPHA_TEST_GREATER;
91      break;
92   case GL_NOTEQUAL:
93      pp_misc |= RADEON_ALPHA_TEST_NEQUAL;
94      break;
95   case GL_GEQUAL:
96      pp_misc |= RADEON_ALPHA_TEST_GEQUAL;
97      break;
98   case GL_ALWAYS:
99      pp_misc |= RADEON_ALPHA_TEST_PASS;
100      break;
101   }
102
103   rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
104}
105
106static void radeonBlendEquationSeparate( GLcontext *ctx,
107					 GLenum modeRGB, GLenum modeA )
108{
109   r100ContextPtr rmesa = R100_CONTEXT(ctx);
110   GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK;
111   GLboolean fallback = GL_FALSE;
112
113   assert( modeRGB == modeA );
114
115   switch ( modeRGB ) {
116   case GL_FUNC_ADD:
117   case GL_LOGIC_OP:
118      b |= RADEON_COMB_FCN_ADD_CLAMP;
119      break;
120
121   case GL_FUNC_SUBTRACT:
122      b |= RADEON_COMB_FCN_SUB_CLAMP;
123      break;
124
125   default:
126      if (ctx->Color.BlendEnabled)
127	 fallback = GL_TRUE;
128      else
129	 b |= RADEON_COMB_FCN_ADD_CLAMP;
130      break;
131   }
132
133   FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, fallback );
134   if ( !fallback ) {
135      RADEON_STATECHANGE( rmesa, ctx );
136      rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
137      if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
138	    && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) {
139	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
140      } else {
141	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
142      }
143   }
144}
145
146static void radeonBlendFuncSeparate( GLcontext *ctx,
147				     GLenum sfactorRGB, GLenum dfactorRGB,
148				     GLenum sfactorA, GLenum dfactorA )
149{
150   r100ContextPtr rmesa = R100_CONTEXT(ctx);
151   GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] &
152      ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
153   GLboolean fallback = GL_FALSE;
154
155   switch ( ctx->Color.BlendSrcRGB ) {
156   case GL_ZERO:
157      b |= RADEON_SRC_BLEND_GL_ZERO;
158      break;
159   case GL_ONE:
160      b |= RADEON_SRC_BLEND_GL_ONE;
161      break;
162   case GL_DST_COLOR:
163      b |= RADEON_SRC_BLEND_GL_DST_COLOR;
164      break;
165   case GL_ONE_MINUS_DST_COLOR:
166      b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
167      break;
168   case GL_SRC_COLOR:
169      b |= RADEON_SRC_BLEND_GL_SRC_COLOR;
170      break;
171   case GL_ONE_MINUS_SRC_COLOR:
172      b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR;
173      break;
174   case GL_SRC_ALPHA:
175      b |= RADEON_SRC_BLEND_GL_SRC_ALPHA;
176      break;
177   case GL_ONE_MINUS_SRC_ALPHA:
178      b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
179      break;
180   case GL_DST_ALPHA:
181      b |= RADEON_SRC_BLEND_GL_DST_ALPHA;
182      break;
183   case GL_ONE_MINUS_DST_ALPHA:
184      b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
185      break;
186   case GL_SRC_ALPHA_SATURATE:
187      b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
188      break;
189   case GL_CONSTANT_COLOR:
190   case GL_ONE_MINUS_CONSTANT_COLOR:
191   case GL_CONSTANT_ALPHA:
192   case GL_ONE_MINUS_CONSTANT_ALPHA:
193      if (ctx->Color.BlendEnabled)
194	 fallback = GL_TRUE;
195      else
196	 b |= RADEON_SRC_BLEND_GL_ONE;
197      break;
198   default:
199      break;
200   }
201
202   switch ( ctx->Color.BlendDstRGB ) {
203   case GL_ZERO:
204      b |= RADEON_DST_BLEND_GL_ZERO;
205      break;
206   case GL_ONE:
207      b |= RADEON_DST_BLEND_GL_ONE;
208      break;
209   case GL_SRC_COLOR:
210      b |= RADEON_DST_BLEND_GL_SRC_COLOR;
211      break;
212   case GL_ONE_MINUS_SRC_COLOR:
213      b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR;
214      break;
215   case GL_SRC_ALPHA:
216      b |= RADEON_DST_BLEND_GL_SRC_ALPHA;
217      break;
218   case GL_ONE_MINUS_SRC_ALPHA:
219      b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
220      break;
221   case GL_DST_COLOR:
222      b |= RADEON_DST_BLEND_GL_DST_COLOR;
223      break;
224   case GL_ONE_MINUS_DST_COLOR:
225      b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR;
226      break;
227   case GL_DST_ALPHA:
228      b |= RADEON_DST_BLEND_GL_DST_ALPHA;
229      break;
230   case GL_ONE_MINUS_DST_ALPHA:
231      b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA;
232      break;
233   case GL_CONSTANT_COLOR:
234   case GL_ONE_MINUS_CONSTANT_COLOR:
235   case GL_CONSTANT_ALPHA:
236   case GL_ONE_MINUS_CONSTANT_ALPHA:
237      if (ctx->Color.BlendEnabled)
238	 fallback = GL_TRUE;
239      else
240	 b |= RADEON_DST_BLEND_GL_ZERO;
241      break;
242   default:
243      break;
244   }
245
246   FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback );
247   if ( !fallback ) {
248      RADEON_STATECHANGE( rmesa, ctx );
249      rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
250   }
251}
252
253
254/* =============================================================
255 * Depth testing
256 */
257
258static void radeonDepthFunc( GLcontext *ctx, GLenum func )
259{
260   r100ContextPtr rmesa = R100_CONTEXT(ctx);
261
262   RADEON_STATECHANGE( rmesa, ctx );
263   rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK;
264
265   switch ( ctx->Depth.Func ) {
266   case GL_NEVER:
267      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEVER;
268      break;
269   case GL_LESS:
270      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LESS;
271      break;
272   case GL_EQUAL:
273      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_EQUAL;
274      break;
275   case GL_LEQUAL:
276      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LEQUAL;
277      break;
278   case GL_GREATER:
279      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GREATER;
280      break;
281   case GL_NOTEQUAL:
282      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEQUAL;
283      break;
284   case GL_GEQUAL:
285      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GEQUAL;
286      break;
287   case GL_ALWAYS:
288      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_ALWAYS;
289      break;
290   }
291}
292
293
294static void radeonDepthMask( GLcontext *ctx, GLboolean flag )
295{
296   r100ContextPtr rmesa = R100_CONTEXT(ctx);
297   RADEON_STATECHANGE( rmesa, ctx );
298
299   if ( ctx->Depth.Mask ) {
300      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |=  RADEON_Z_WRITE_ENABLE;
301   } else {
302      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_WRITE_ENABLE;
303   }
304}
305
306static void radeonClearDepth( GLcontext *ctx, GLclampd d )
307{
308   r100ContextPtr rmesa = R100_CONTEXT(ctx);
309   GLuint format = (rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &
310		    RADEON_DEPTH_FORMAT_MASK);
311
312   switch ( format ) {
313   case RADEON_DEPTH_FORMAT_16BIT_INT_Z:
314      rmesa->radeon.state.depth.clear = d * 0x0000ffff;
315      break;
316   case RADEON_DEPTH_FORMAT_24BIT_INT_Z:
317      rmesa->radeon.state.depth.clear = d * 0x00ffffff;
318      break;
319   }
320}
321
322
323/* =============================================================
324 * Fog
325 */
326
327
328static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
329{
330   r100ContextPtr rmesa = R100_CONTEXT(ctx);
331   union { int i; float f; } c, d;
332   GLchan col[4];
333
334   switch (pname) {
335   case GL_FOG_MODE:
336      if (!ctx->Fog.Enabled)
337	 return;
338      RADEON_STATECHANGE(rmesa, tcl);
339      rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
340      switch (ctx->Fog.Mode) {
341      case GL_LINEAR:
342	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
343	 break;
344      case GL_EXP:
345	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
346	 break;
347      case GL_EXP2:
348	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
349	 break;
350      default:
351	 return;
352      }
353   /* fallthrough */
354   case GL_FOG_DENSITY:
355   case GL_FOG_START:
356   case GL_FOG_END:
357      if (!ctx->Fog.Enabled)
358	 return;
359      c.i = rmesa->hw.fog.cmd[FOG_C];
360      d.i = rmesa->hw.fog.cmd[FOG_D];
361      switch (ctx->Fog.Mode) {
362      case GL_EXP:
363	 c.f = 0.0;
364	 /* While this is the opposite sign from the DDK, it makes the fog test
365	  * pass, and matches r200.
366	  */
367	 d.f = -ctx->Fog.Density;
368	 break;
369      case GL_EXP2:
370	 c.f = 0.0;
371	 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
372	 break;
373      case GL_LINEAR:
374	 if (ctx->Fog.Start == ctx->Fog.End) {
375	    c.f = 1.0F;
376	    d.f = 1.0F;
377	 } else {
378	    c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
379	    /* While this is the opposite sign from the DDK, it makes the fog
380	     * test pass, and matches r200.
381	     */
382	    d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
383	 }
384	 break;
385      default:
386	 break;
387      }
388      if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
389	 RADEON_STATECHANGE( rmesa, fog );
390	 rmesa->hw.fog.cmd[FOG_C] = c.i;
391	 rmesa->hw.fog.cmd[FOG_D] = d.i;
392      }
393      break;
394   case GL_FOG_COLOR:
395      RADEON_STATECHANGE( rmesa, ctx );
396      UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
397      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
398      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
399	 radeonPackColor( 4, col[0], col[1], col[2], 0 );
400      break;
401   case GL_FOG_COORD_SRC:
402      radeonUpdateSpecular( ctx );
403      break;
404   default:
405      return;
406   }
407}
408
409/* =============================================================
410 * Culling
411 */
412
413static void radeonCullFace( GLcontext *ctx, GLenum unused )
414{
415   r100ContextPtr rmesa = R100_CONTEXT(ctx);
416   GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
417   GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
418
419   s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;
420   t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK);
421
422   if ( ctx->Polygon.CullFlag ) {
423      switch ( ctx->Polygon.CullFaceMode ) {
424      case GL_FRONT:
425	 s &= ~RADEON_FFACE_SOLID;
426	 t |= RADEON_CULL_FRONT;
427	 break;
428      case GL_BACK:
429	 s &= ~RADEON_BFACE_SOLID;
430	 t |= RADEON_CULL_BACK;
431	 break;
432      case GL_FRONT_AND_BACK:
433	 s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);
434	 t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK);
435	 break;
436      }
437   }
438
439   if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
440      RADEON_STATECHANGE(rmesa, set );
441      rmesa->hw.set.cmd[SET_SE_CNTL] = s;
442   }
443
444   if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
445      RADEON_STATECHANGE(rmesa, tcl );
446      rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
447   }
448}
449
450static void radeonFrontFace( GLcontext *ctx, GLenum mode )
451{
452   r100ContextPtr rmesa = R100_CONTEXT(ctx);
453
454   RADEON_STATECHANGE( rmesa, set );
455   rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK;
456
457   RADEON_STATECHANGE( rmesa, tcl );
458   rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;
459
460   switch ( mode ) {
461   case GL_CW:
462      rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW;
463      break;
464   case GL_CCW:
465      rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CCW;
466      rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW;
467      break;
468   }
469}
470
471
472/* =============================================================
473 * Line state
474 */
475static void radeonLineWidth( GLcontext *ctx, GLfloat widthf )
476{
477   r100ContextPtr rmesa = R100_CONTEXT(ctx);
478
479   RADEON_STATECHANGE( rmesa, lin );
480   RADEON_STATECHANGE( rmesa, set );
481
482   /* Line width is stored in U6.4 format.
483    */
484   rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0);
485   if ( widthf > 1.0 ) {
486      rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_WIDELINE_ENABLE;
487   } else {
488      rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE;
489   }
490}
491
492static void radeonLineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
493{
494   r100ContextPtr rmesa = R100_CONTEXT(ctx);
495
496   RADEON_STATECHANGE( rmesa, lin );
497   rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
498      ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
499}
500
501
502/* =============================================================
503 * Masks
504 */
505static void radeonColorMask( GLcontext *ctx,
506			     GLboolean r, GLboolean g,
507			     GLboolean b, GLboolean a )
508{
509   r100ContextPtr rmesa = R100_CONTEXT(ctx);
510   GLuint mask = radeonPackColor( rmesa->radeon.radeonScreen->cpp,
511				  ctx->Color.ColorMask[RCOMP],
512				  ctx->Color.ColorMask[GCOMP],
513				  ctx->Color.ColorMask[BCOMP],
514				  ctx->Color.ColorMask[ACOMP] );
515
516   if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
517      RADEON_STATECHANGE( rmesa, msk );
518      rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
519   }
520}
521
522
523/* =============================================================
524 * Polygon state
525 */
526
527static void radeonPolygonOffset( GLcontext *ctx,
528				 GLfloat factor, GLfloat units )
529{
530   r100ContextPtr rmesa = R100_CONTEXT(ctx);
531   float_ui32_type constant =  { units * rmesa->radeon.state.depth.scale };
532   float_ui32_type factoru = { factor };
533
534   RADEON_STATECHANGE( rmesa, zbs );
535   rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR]   = factoru.ui32;
536   rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
537}
538
539static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask )
540{
541   r100ContextPtr rmesa = R100_CONTEXT(ctx);
542   GLuint i;
543   drm_radeon_stipple_t stipple;
544
545   /* Must flip pattern upside down.
546    */
547   for ( i = 0 ; i < 32 ; i++ ) {
548      rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i];
549   }
550
551   /* TODO: push this into cmd mechanism
552    */
553   radeon_firevertices(&rmesa->radeon);
554   LOCK_HARDWARE( &rmesa->radeon );
555
556   /* FIXME: Use window x,y offsets into stipple RAM.
557    */
558   stipple.mask = rmesa->state.stipple.mask;
559   drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE,
560                    &stipple, sizeof(drm_radeon_stipple_t) );
561   UNLOCK_HARDWARE( &rmesa->radeon );
562}
563
564static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
565{
566   r100ContextPtr rmesa = R100_CONTEXT(ctx);
567   GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
568
569   /* Can't generally do unfilled via tcl, but some good special
570    * cases work.
571    */
572   TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag);
573   if (rmesa->radeon.TclFallback) {
574      radeonChooseRenderState( ctx );
575      radeonChooseVertexState( ctx );
576   }
577}
578
579
580/* =============================================================
581 * Rendering attributes
582 *
583 * We really don't want to recalculate all this every time we bind a
584 * texture.  These things shouldn't change all that often, so it makes
585 * sense to break them out of the core texture state update routines.
586 */
587
588/* Examine lighting and texture state to determine if separate specular
589 * should be enabled.
590 */
591static void radeonUpdateSpecular( GLcontext *ctx )
592{
593   r100ContextPtr rmesa = R100_CONTEXT(ctx);
594   uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
595   GLuint flag = 0;
596
597   RADEON_STATECHANGE( rmesa, tcl );
598
599   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
600   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
601   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
602   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE;
603   rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
604
605   p &= ~RADEON_SPECULAR_ENABLE;
606
607   rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE;
608
609
610   if (ctx->Light.Enabled &&
611       ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
612      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
613      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
614      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
615      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
616      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
617      p |=  RADEON_SPECULAR_ENABLE;
618      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
619	 ~RADEON_DIFFUSE_SPECULAR_COMBINE;
620   }
621   else if (ctx->Light.Enabled) {
622      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
623      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
624      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
625   } else if (ctx->Fog.ColorSumEnabled ) {
626      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
627      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
628      p |= RADEON_SPECULAR_ENABLE;
629   } else {
630      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
631   }
632
633   if (ctx->Fog.Enabled) {
634      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
635      if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
636	 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
637      /* Bizzare: have to leave lighting enabled to get fog. */
638	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
639      }
640      else {
641      /* cannot do tcl fog factor calculation with fog coord source
642       * (send precomputed factors). Cannot use precomputed fog
643       * factors together with tcl spec light (need tcl fallback) */
644	 flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
645	    RADEON_TCL_COMPUTE_SPECULAR) != 0;
646      }
647   }
648
649   TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
650
651   if (NEED_SECONDARY_COLOR(ctx)) {
652      assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
653   } else {
654      assert( (p & RADEON_SPECULAR_ENABLE) == 0 );
655   }
656
657   if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
658      RADEON_STATECHANGE( rmesa, ctx );
659      rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
660   }
661
662   /* Update vertex/render formats
663    */
664   if (rmesa->radeon.TclFallback) {
665      radeonChooseRenderState( ctx );
666      radeonChooseVertexState( ctx );
667   }
668}
669
670
671/* =============================================================
672 * Materials
673 */
674
675
676/* Update on colormaterial, material emmissive/ambient,
677 * lightmodel.globalambient
678 */
679static void update_global_ambient( GLcontext *ctx )
680{
681   r100ContextPtr rmesa = R100_CONTEXT(ctx);
682   float *fcmd = (float *)RADEON_DB_STATE( glt );
683
684   /* Need to do more if both emmissive & ambient are PREMULT:
685    * Hope this is not needed for MULT
686    */
687   if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
688       ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
689	(3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
690   {
691      COPY_3V( &fcmd[GLT_RED],
692	       ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
693      ACC_SCALE_3V( &fcmd[GLT_RED],
694		   ctx->Light.Model.Ambient,
695		   ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
696   }
697   else
698   {
699      COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
700   }
701
702   RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
703}
704
705/* Update on change to
706 *    - light[p].colors
707 *    - light[p].enabled
708 */
709static void update_light_colors( GLcontext *ctx, GLuint p )
710{
711   struct gl_light *l = &ctx->Light.Light[p];
712
713/*     fprintf(stderr, "%s\n", __FUNCTION__); */
714
715   if (l->Enabled) {
716      r100ContextPtr rmesa = R100_CONTEXT(ctx);
717      float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
718
719      COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
720      COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
721      COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
722
723      RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
724   }
725}
726
727/* Also fallback for asym colormaterial mode in twoside lighting...
728 */
729static void check_twoside_fallback( GLcontext *ctx )
730{
731   GLboolean fallback = GL_FALSE;
732   GLint i;
733
734   if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
735      if (ctx->Light.ColorMaterialEnabled &&
736	  (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
737	  ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
738	 fallback = GL_TRUE;
739      else {
740	 for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
741	    if (memcmp( ctx->Light.Material.Attrib[i],
742			ctx->Light.Material.Attrib[i+1],
743			sizeof(GLfloat)*4) != 0) {
744	       fallback = GL_TRUE;
745	       break;
746	    }
747      }
748   }
749
750   TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
751}
752
753
754static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
755{
756      r100ContextPtr rmesa = R100_CONTEXT(ctx);
757      GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
758
759      light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
760			   (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
761			   (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
762			   (3 << RADEON_SPECULAR_SOURCE_SHIFT));
763
764   if (ctx->Light.ColorMaterialEnabled) {
765      GLuint mask = ctx->Light.ColorMaterialBitmask;
766
767      if (mask & MAT_BIT_FRONT_EMISSION) {
768	 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
769			     RADEON_EMISSIVE_SOURCE_SHIFT);
770      }
771      else {
772	 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
773			     RADEON_EMISSIVE_SOURCE_SHIFT);
774      }
775
776      if (mask & MAT_BIT_FRONT_AMBIENT) {
777	 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
778			     RADEON_AMBIENT_SOURCE_SHIFT);
779      }
780      else {
781	 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
782			     RADEON_AMBIENT_SOURCE_SHIFT);
783      }
784
785      if (mask & MAT_BIT_FRONT_DIFFUSE) {
786	 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
787			     RADEON_DIFFUSE_SOURCE_SHIFT);
788      }
789      else {
790	 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
791			     RADEON_DIFFUSE_SOURCE_SHIFT);
792      }
793
794      if (mask & MAT_BIT_FRONT_SPECULAR) {
795	 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
796			     RADEON_SPECULAR_SOURCE_SHIFT);
797      }
798      else {
799	 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
800			     RADEON_SPECULAR_SOURCE_SHIFT);
801      }
802   }
803   else {
804   /* Default to MULT:
805    */
806      light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
807		   (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
808		   (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
809		   (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
810   }
811
812      if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
813	 RADEON_STATECHANGE( rmesa, tcl );
814	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
815   }
816}
817
818void radeonUpdateMaterial( GLcontext *ctx )
819{
820   r100ContextPtr rmesa = R100_CONTEXT(ctx);
821   GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
822   GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
823   GLuint mask = ~0;
824
825   if (ctx->Light.ColorMaterialEnabled)
826      mask &= ~ctx->Light.ColorMaterialBitmask;
827
828   if (RADEON_DEBUG & DEBUG_STATE)
829      fprintf(stderr, "%s\n", __FUNCTION__);
830
831
832   if (mask & MAT_BIT_FRONT_EMISSION) {
833      fcmd[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_FRONT_EMISSION][0];
834      fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
835      fcmd[MTL_EMMISSIVE_BLUE]  = mat[MAT_ATTRIB_FRONT_EMISSION][2];
836      fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
837   }
838   if (mask & MAT_BIT_FRONT_AMBIENT) {
839      fcmd[MTL_AMBIENT_RED]     = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
840      fcmd[MTL_AMBIENT_GREEN]   = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
841      fcmd[MTL_AMBIENT_BLUE]    = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
842      fcmd[MTL_AMBIENT_ALPHA]   = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
843   }
844   if (mask & MAT_BIT_FRONT_DIFFUSE) {
845      fcmd[MTL_DIFFUSE_RED]     = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
846      fcmd[MTL_DIFFUSE_GREEN]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
847      fcmd[MTL_DIFFUSE_BLUE]    = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
848      fcmd[MTL_DIFFUSE_ALPHA]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
849   }
850   if (mask & MAT_BIT_FRONT_SPECULAR) {
851      fcmd[MTL_SPECULAR_RED]    = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
852      fcmd[MTL_SPECULAR_GREEN]  = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
853      fcmd[MTL_SPECULAR_BLUE]   = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
854      fcmd[MTL_SPECULAR_ALPHA]  = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
855   }
856   if (mask & MAT_BIT_FRONT_SHININESS) {
857      fcmd[MTL_SHININESS]       = mat[MAT_ATTRIB_FRONT_SHININESS][0];
858   }
859
860   RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl );
861
862   check_twoside_fallback( ctx );
863/*   update_global_ambient( ctx );*/
864}
865
866/* _NEW_LIGHT
867 * _NEW_MODELVIEW
868 * _MESA_NEW_NEED_EYE_COORDS
869 *
870 * Uses derived state from mesa:
871 *       _VP_inf_norm
872 *       _h_inf_norm
873 *       _Position
874 *       _NormDirection
875 *       _ModelViewInvScale
876 *       _NeedEyeCoords
877 *       _EyeZDir
878 *
879 * which are calculated in light.c and are correct for the current
880 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
881 * and _MESA_NEW_NEED_EYE_COORDS.
882 */
883static void update_light( GLcontext *ctx )
884{
885   r100ContextPtr rmesa = R100_CONTEXT(ctx);
886
887   /* Have to check these, or have an automatic shortcircuit mechanism
888    * to remove noop statechanges. (Or just do a better job on the
889    * front end).
890    */
891   {
892      GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
893
894      if (ctx->_NeedEyeCoords)
895	 tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
896      else
897	 tmp |= RADEON_LIGHT_IN_MODELSPACE;
898
899
900      /* Leave this test disabled: (unexplained q3 lockup) (even with
901         new packets)
902      */
903      if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
904      {
905	 RADEON_STATECHANGE( rmesa, tcl );
906	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
907      }
908   }
909
910   {
911      GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
912      fcmd[EYE_X] = ctx->_EyeZDir[0];
913      fcmd[EYE_Y] = ctx->_EyeZDir[1];
914      fcmd[EYE_Z] = - ctx->_EyeZDir[2];
915      fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
916      RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
917   }
918
919
920
921   if (ctx->Light.Enabled) {
922      GLint p;
923      for (p = 0 ; p < MAX_LIGHTS; p++) {
924	 if (ctx->Light.Light[p].Enabled) {
925	    struct gl_light *l = &ctx->Light.Light[p];
926	    GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
927
928	    if (l->EyePosition[3] == 0.0) {
929	       COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
930	       COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
931	       fcmd[LIT_POSITION_W] = 0;
932	       fcmd[LIT_DIRECTION_W] = 0;
933	    } else {
934	       COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
935	       fcmd[LIT_DIRECTION_X] = -l->_NormDirection[0];
936	       fcmd[LIT_DIRECTION_Y] = -l->_NormDirection[1];
937	       fcmd[LIT_DIRECTION_Z] = -l->_NormDirection[2];
938	       fcmd[LIT_DIRECTION_W] = 0;
939	    }
940
941	    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
942	 }
943      }
944   }
945}
946
947static void radeonLightfv( GLcontext *ctx, GLenum light,
948			   GLenum pname, const GLfloat *params )
949{
950   r100ContextPtr rmesa = R100_CONTEXT(ctx);
951   GLint p = light - GL_LIGHT0;
952   struct gl_light *l = &ctx->Light.Light[p];
953   GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
954
955
956   switch (pname) {
957   case GL_AMBIENT:
958   case GL_DIFFUSE:
959   case GL_SPECULAR:
960      update_light_colors( ctx, p );
961      break;
962
963   case GL_SPOT_DIRECTION:
964      /* picked up in update_light */
965      break;
966
967   case GL_POSITION: {
968      /* positions picked up in update_light, but can do flag here */
969      GLuint flag;
970      GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
971
972      /* FIXME: Set RANGE_ATTEN only when needed */
973      if (p&1)
974	 flag = RADEON_LIGHT_1_IS_LOCAL;
975      else
976	 flag = RADEON_LIGHT_0_IS_LOCAL;
977
978      RADEON_STATECHANGE(rmesa, tcl);
979      if (l->EyePosition[3] != 0.0F)
980	 rmesa->hw.tcl.cmd[idx] |= flag;
981      else
982	 rmesa->hw.tcl.cmd[idx] &= ~flag;
983      break;
984   }
985
986   case GL_SPOT_EXPONENT:
987      RADEON_STATECHANGE(rmesa, lit[p]);
988      fcmd[LIT_SPOT_EXPONENT] = params[0];
989      break;
990
991   case GL_SPOT_CUTOFF: {
992      GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
993      GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
994
995      RADEON_STATECHANGE(rmesa, lit[p]);
996      fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
997
998      RADEON_STATECHANGE(rmesa, tcl);
999      if (l->SpotCutoff != 180.0F)
1000	 rmesa->hw.tcl.cmd[idx] |= flag;
1001      else
1002	 rmesa->hw.tcl.cmd[idx] &= ~flag;
1003
1004      break;
1005   }
1006
1007   case GL_CONSTANT_ATTENUATION:
1008      RADEON_STATECHANGE(rmesa, lit[p]);
1009      fcmd[LIT_ATTEN_CONST] = params[0];
1010      if ( params[0] == 0.0 )
1011	 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
1012      else
1013	 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
1014      break;
1015   case GL_LINEAR_ATTENUATION:
1016      RADEON_STATECHANGE(rmesa, lit[p]);
1017      fcmd[LIT_ATTEN_LINEAR] = params[0];
1018      break;
1019   case GL_QUADRATIC_ATTENUATION:
1020      RADEON_STATECHANGE(rmesa, lit[p]);
1021      fcmd[LIT_ATTEN_QUADRATIC] = params[0];
1022      break;
1023   default:
1024      return;
1025   }
1026
1027   /* Set RANGE_ATTEN only when needed */
1028   switch (pname) {
1029   case GL_POSITION:
1030   case GL_CONSTANT_ATTENUATION:
1031   case GL_LINEAR_ATTENUATION:
1032   case GL_QUADRATIC_ATTENUATION:
1033   {
1034      GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
1035      GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1036      GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1037				  : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
1038      GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1039				  : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
1040
1041      if ( l->EyePosition[3] == 0.0F ||
1042	   ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1043	     fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1044	 /* Disable attenuation */
1045	 icmd[idx] &= ~atten_flag;
1046      } else {
1047	 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1048	    /* Enable only constant portion of attenuation calculation */
1049	    icmd[idx] |= ( atten_flag | atten_const_flag );
1050	 } else {
1051	    /* Enable full attenuation calculation */
1052	    icmd[idx] &= ~atten_const_flag;
1053	    icmd[idx] |= atten_flag;
1054	 }
1055      }
1056
1057      RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1058      break;
1059   }
1060   default:
1061      break;
1062   }
1063}
1064
1065
1066
1067
1068static void radeonLightModelfv( GLcontext *ctx, GLenum pname,
1069				const GLfloat *param )
1070{
1071   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1072
1073   switch (pname) {
1074      case GL_LIGHT_MODEL_AMBIENT:
1075	 update_global_ambient( ctx );
1076	 break;
1077
1078      case GL_LIGHT_MODEL_LOCAL_VIEWER:
1079	 RADEON_STATECHANGE( rmesa, tcl );
1080	 if (ctx->Light.Model.LocalViewer)
1081	    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
1082	 else
1083	    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
1084         break;
1085
1086      case GL_LIGHT_MODEL_TWO_SIDE:
1087	 RADEON_STATECHANGE( rmesa, tcl );
1088	 if (ctx->Light.Model.TwoSide)
1089	    rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
1090	 else
1091	    rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
1092
1093	 check_twoside_fallback( ctx );
1094
1095	 if (rmesa->radeon.TclFallback) {
1096	    radeonChooseRenderState( ctx );
1097	    radeonChooseVertexState( ctx );
1098	 }
1099         break;
1100
1101      case GL_LIGHT_MODEL_COLOR_CONTROL:
1102	 radeonUpdateSpecular(ctx);
1103         break;
1104
1105      default:
1106         break;
1107   }
1108}
1109
1110static void radeonShadeModel( GLcontext *ctx, GLenum mode )
1111{
1112   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1113   GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1114
1115   s &= ~(RADEON_DIFFUSE_SHADE_MASK |
1116	  RADEON_ALPHA_SHADE_MASK |
1117	  RADEON_SPECULAR_SHADE_MASK |
1118	  RADEON_FOG_SHADE_MASK);
1119
1120   switch ( mode ) {
1121   case GL_FLAT:
1122      s |= (RADEON_DIFFUSE_SHADE_FLAT |
1123	    RADEON_ALPHA_SHADE_FLAT |
1124	    RADEON_SPECULAR_SHADE_FLAT |
1125	    RADEON_FOG_SHADE_FLAT);
1126      break;
1127   case GL_SMOOTH:
1128      s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
1129	    RADEON_ALPHA_SHADE_GOURAUD |
1130	    RADEON_SPECULAR_SHADE_GOURAUD |
1131	    RADEON_FOG_SHADE_GOURAUD);
1132      break;
1133   default:
1134      return;
1135   }
1136
1137   if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1138      RADEON_STATECHANGE( rmesa, set );
1139      rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1140   }
1141}
1142
1143
1144/* =============================================================
1145 * User clip planes
1146 */
1147
1148static void radeonClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
1149{
1150   GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1151   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1152   GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1153
1154   RADEON_STATECHANGE( rmesa, ucp[p] );
1155   rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1156   rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1157   rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1158   rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1159}
1160
1161static void radeonUpdateClipPlanes( GLcontext *ctx )
1162{
1163   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1164   GLuint p;
1165
1166   for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1167      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1168	 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1169
1170	 RADEON_STATECHANGE( rmesa, ucp[p] );
1171	 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1172	 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1173	 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1174	 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1175      }
1176   }
1177}
1178
1179
1180/* =============================================================
1181 * Stencil
1182 */
1183
1184static void
1185radeonStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
1186                           GLint ref, GLuint mask )
1187{
1188   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1189   GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) |
1190		     ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
1191
1192   RADEON_STATECHANGE( rmesa, ctx );
1193   RADEON_STATECHANGE( rmesa, msk );
1194
1195   rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
1196   rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
1197						   RADEON_STENCIL_VALUE_MASK);
1198
1199   switch ( ctx->Stencil.Function[0] ) {
1200   case GL_NEVER:
1201      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
1202      break;
1203   case GL_LESS:
1204      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
1205      break;
1206   case GL_EQUAL:
1207      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
1208      break;
1209   case GL_LEQUAL:
1210      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
1211      break;
1212   case GL_GREATER:
1213      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
1214      break;
1215   case GL_NOTEQUAL:
1216      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
1217      break;
1218   case GL_GEQUAL:
1219      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
1220      break;
1221   case GL_ALWAYS:
1222      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
1223      break;
1224   }
1225
1226   rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1227}
1228
1229static void
1230radeonStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
1231{
1232   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1233
1234   RADEON_STATECHANGE( rmesa, msk );
1235   rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
1236   rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1237      ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
1238}
1239
1240static void radeonStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail,
1241                                     GLenum zfail, GLenum zpass )
1242{
1243   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1244
1245   /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1246      and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1247      but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1248
1249   GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
1250   GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
1251   GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1252   GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1253   GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1254   GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
1255
1256   if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
1257      tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
1258      tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
1259      tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
1260      tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
1261      tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
1262      tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
1263   }
1264   else {
1265      tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
1266      tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
1267      tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
1268      tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
1269      tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
1270      tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
1271   }
1272
1273   RADEON_STATECHANGE( rmesa, ctx );
1274   rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1275					       RADEON_STENCIL_ZFAIL_MASK |
1276					       RADEON_STENCIL_ZPASS_MASK);
1277
1278   switch ( ctx->Stencil.FailFunc[0] ) {
1279   case GL_KEEP:
1280      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1281      break;
1282   case GL_ZERO:
1283      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1284      break;
1285   case GL_REPLACE:
1286      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1287      break;
1288   case GL_INCR:
1289      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1290      break;
1291   case GL_DECR:
1292      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1293      break;
1294   case GL_INCR_WRAP:
1295      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
1296      break;
1297   case GL_DECR_WRAP:
1298      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
1299      break;
1300   case GL_INVERT:
1301      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1302      break;
1303   }
1304
1305   switch ( ctx->Stencil.ZFailFunc[0] ) {
1306   case GL_KEEP:
1307      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1308      break;
1309   case GL_ZERO:
1310      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1311      break;
1312   case GL_REPLACE:
1313      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1314      break;
1315   case GL_INCR:
1316      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1317      break;
1318   case GL_DECR:
1319      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1320      break;
1321   case GL_INCR_WRAP:
1322      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1323      break;
1324   case GL_DECR_WRAP:
1325      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1326      break;
1327   case GL_INVERT:
1328      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1329      break;
1330   }
1331
1332   switch ( ctx->Stencil.ZPassFunc[0] ) {
1333   case GL_KEEP:
1334      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1335      break;
1336   case GL_ZERO:
1337      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1338      break;
1339   case GL_REPLACE:
1340      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1341      break;
1342   case GL_INCR:
1343      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1344      break;
1345   case GL_DECR:
1346      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1347      break;
1348   case GL_INCR_WRAP:
1349      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
1350      break;
1351   case GL_DECR_WRAP:
1352      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1353      break;
1354   case GL_INVERT:
1355      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1356      break;
1357   }
1358}
1359
1360static void radeonClearStencil( GLcontext *ctx, GLint s )
1361{
1362   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1363
1364   rmesa->radeon.state.stencil.clear =
1365      ((GLuint) (ctx->Stencil.Clear & 0xff) |
1366       (0xff << RADEON_STENCIL_MASK_SHIFT) |
1367       ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT));
1368}
1369
1370
1371/* =============================================================
1372 * Window position and viewport transformation
1373 */
1374
1375/*
1376 * To correctly position primitives:
1377 */
1378#define SUBPIXEL_X 0.125
1379#define SUBPIXEL_Y 0.125
1380
1381
1382/**
1383 * Called when window size or position changes or viewport or depth range
1384 * state is changed.  We update the hardware viewport state here.
1385 */
1386void radeonUpdateWindow( GLcontext *ctx )
1387{
1388   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1389   __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
1390   GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
1391   GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
1392   const GLfloat *v = ctx->Viewport._WindowMap.m;
1393   const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
1394   GLfloat y_scale, y_bias;
1395
1396   if (render_to_fbo) {
1397      y_scale = 1.0;
1398      y_bias = 0;
1399   } else {
1400      y_scale = -1.0;
1401      y_bias = yoffset;
1402   }
1403
1404   float_ui32_type sx = { v[MAT_SX] };
1405   float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
1406   float_ui32_type sy = { v[MAT_SY] * y_scale };
1407   float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
1408   float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale };
1409   float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale };
1410
1411   RADEON_STATECHANGE( rmesa, vpt );
1412
1413   rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = sx.ui32;
1414   rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1415   rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE]  = sy.ui32;
1416   rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1417   rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE]  = sz.ui32;
1418   rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1419}
1420
1421
1422static void radeonViewport( GLcontext *ctx, GLint x, GLint y,
1423			    GLsizei width, GLsizei height )
1424{
1425   /* Don't pipeline viewport changes, conflict with window offset
1426    * setting below.  Could apply deltas to rescue pipelined viewport
1427    * values, or keep the originals hanging around.
1428    */
1429   radeonUpdateWindow( ctx );
1430
1431   radeon_viewport(ctx, x, y, width, height);
1432}
1433
1434static void radeonDepthRange( GLcontext *ctx, GLclampd nearval,
1435			      GLclampd farval )
1436{
1437   radeonUpdateWindow( ctx );
1438}
1439
1440void radeonUpdateViewportOffset( GLcontext *ctx )
1441{
1442   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1443   __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
1444   GLfloat xoffset = (GLfloat)dPriv->x;
1445   GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1446   const GLfloat *v = ctx->Viewport._WindowMap.m;
1447
1448   float_ui32_type tx;
1449   float_ui32_type ty;
1450
1451   tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X;
1452   ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1453
1454   if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
1455	rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
1456   {
1457      /* Note: this should also modify whatever data the context reset
1458       * code uses...
1459       */
1460      RADEON_STATECHANGE( rmesa, vpt );
1461      rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1462      rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1463
1464      /* update polygon stipple x/y screen offset */
1465      {
1466         GLuint stx, sty;
1467         GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1468
1469         m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
1470                RADEON_STIPPLE_Y_OFFSET_MASK);
1471
1472         /* add magic offsets, then invert */
1473         stx = 31 - ((rmesa->radeon.dri.drawable->x - 1) & RADEON_STIPPLE_COORD_MASK);
1474         sty = 31 - ((rmesa->radeon.dri.drawable->y + rmesa->radeon.dri.drawable->h - 1)
1475                     & RADEON_STIPPLE_COORD_MASK);
1476
1477         m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
1478               (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
1479
1480         if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1481            RADEON_STATECHANGE( rmesa, msc );
1482	    rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1483         }
1484      }
1485   }
1486
1487   radeonUpdateScissor( ctx );
1488}
1489
1490
1491
1492/* =============================================================
1493 * Miscellaneous
1494 */
1495
1496static void radeonClearColor( GLcontext *ctx, const GLfloat color[4] )
1497{
1498   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1499   GLubyte c[4];
1500   CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
1501   CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
1502   CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
1503   CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
1504   rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp,
1505					       c[0], c[1], c[2], c[3] );
1506}
1507
1508
1509static void radeonRenderMode( GLcontext *ctx, GLenum mode )
1510{
1511   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1512   FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1513}
1514
1515
1516static GLuint radeon_rop_tab[] = {
1517   RADEON_ROP_CLEAR,
1518   RADEON_ROP_AND,
1519   RADEON_ROP_AND_REVERSE,
1520   RADEON_ROP_COPY,
1521   RADEON_ROP_AND_INVERTED,
1522   RADEON_ROP_NOOP,
1523   RADEON_ROP_XOR,
1524   RADEON_ROP_OR,
1525   RADEON_ROP_NOR,
1526   RADEON_ROP_EQUIV,
1527   RADEON_ROP_INVERT,
1528   RADEON_ROP_OR_REVERSE,
1529   RADEON_ROP_COPY_INVERTED,
1530   RADEON_ROP_OR_INVERTED,
1531   RADEON_ROP_NAND,
1532   RADEON_ROP_SET,
1533};
1534
1535static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode )
1536{
1537   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1538   GLuint rop = (GLuint)opcode - GL_CLEAR;
1539
1540   ASSERT( rop < 16 );
1541
1542   RADEON_STATECHANGE( rmesa, msk );
1543   rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1544}
1545
1546/* =============================================================
1547 * State enable/disable
1548 */
1549
1550static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
1551{
1552   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1553   GLuint p, flag;
1554
1555   if ( RADEON_DEBUG & DEBUG_STATE )
1556      fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1557	       _mesa_lookup_enum_by_nr( cap ),
1558	       state ? "GL_TRUE" : "GL_FALSE" );
1559
1560   switch ( cap ) {
1561      /* Fast track this one...
1562       */
1563   case GL_TEXTURE_1D:
1564   case GL_TEXTURE_2D:
1565   case GL_TEXTURE_3D:
1566      break;
1567
1568   case GL_ALPHA_TEST:
1569      RADEON_STATECHANGE( rmesa, ctx );
1570      if (state) {
1571	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1572      } else {
1573	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1574      }
1575      break;
1576
1577   case GL_BLEND:
1578      RADEON_STATECHANGE( rmesa, ctx );
1579      if (state) {
1580	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ALPHA_BLEND_ENABLE;
1581      } else {
1582	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1583      }
1584      if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1585	    && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) {
1586	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
1587      } else {
1588	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1589      }
1590
1591      /* Catch a possible fallback:
1592       */
1593      if (state) {
1594	 ctx->Driver.BlendEquationSeparate( ctx,
1595					    ctx->Color.BlendEquationRGB,
1596					    ctx->Color.BlendEquationA );
1597	 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.BlendSrcRGB,
1598					ctx->Color.BlendDstRGB,
1599					ctx->Color.BlendSrcA,
1600					ctx->Color.BlendDstA );
1601      }
1602      else {
1603	 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1604	 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1605      }
1606      break;
1607
1608   case GL_CLIP_PLANE0:
1609   case GL_CLIP_PLANE1:
1610   case GL_CLIP_PLANE2:
1611   case GL_CLIP_PLANE3:
1612   case GL_CLIP_PLANE4:
1613   case GL_CLIP_PLANE5:
1614      p = cap-GL_CLIP_PLANE0;
1615      RADEON_STATECHANGE( rmesa, tcl );
1616      if (state) {
1617	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1618	 radeonClipPlane( ctx, cap, NULL );
1619      }
1620      else {
1621	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1622      }
1623      break;
1624
1625   case GL_COLOR_MATERIAL:
1626      radeonColorMaterial( ctx, 0, 0 );
1627      radeonUpdateMaterial( ctx );
1628      break;
1629
1630   case GL_CULL_FACE:
1631      radeonCullFace( ctx, 0 );
1632      break;
1633
1634   case GL_DEPTH_TEST:
1635      RADEON_STATECHANGE(rmesa, ctx );
1636      if ( state ) {
1637	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_Z_ENABLE;
1638      } else {
1639	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1640      }
1641      break;
1642
1643   case GL_DITHER:
1644      RADEON_STATECHANGE(rmesa, ctx );
1645      if ( state ) {
1646	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_DITHER_ENABLE;
1647	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1648      } else {
1649	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1650	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  rmesa->radeon.state.color.roundEnable;
1651      }
1652      break;
1653
1654   case GL_FOG:
1655      RADEON_STATECHANGE(rmesa, ctx );
1656      if ( state ) {
1657	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1658	 radeonFogfv( ctx, GL_FOG_MODE, NULL );
1659      } else {
1660	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1661	 RADEON_STATECHANGE(rmesa, tcl);
1662	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1663      }
1664      radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1665      _mesa_allow_light_in_model( ctx, !state );
1666      break;
1667
1668   case GL_LIGHT0:
1669   case GL_LIGHT1:
1670   case GL_LIGHT2:
1671   case GL_LIGHT3:
1672   case GL_LIGHT4:
1673   case GL_LIGHT5:
1674   case GL_LIGHT6:
1675   case GL_LIGHT7:
1676      RADEON_STATECHANGE(rmesa, tcl);
1677      p = cap - GL_LIGHT0;
1678      if (p&1)
1679	 flag = (RADEON_LIGHT_1_ENABLE |
1680		 RADEON_LIGHT_1_ENABLE_AMBIENT |
1681		 RADEON_LIGHT_1_ENABLE_SPECULAR);
1682      else
1683	 flag = (RADEON_LIGHT_0_ENABLE |
1684		 RADEON_LIGHT_0_ENABLE_AMBIENT |
1685		 RADEON_LIGHT_0_ENABLE_SPECULAR);
1686
1687      if (state)
1688	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1689      else
1690	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1691
1692      /*
1693       */
1694      update_light_colors( ctx, p );
1695      break;
1696
1697   case GL_LIGHTING:
1698      RADEON_STATECHANGE(rmesa, tcl);
1699      radeonUpdateSpecular(ctx);
1700      check_twoside_fallback( ctx );
1701      break;
1702
1703   case GL_LINE_SMOOTH:
1704      RADEON_STATECHANGE( rmesa, ctx );
1705      if ( state ) {
1706	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_LINE;
1707      } else {
1708	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1709      }
1710      break;
1711
1712   case GL_LINE_STIPPLE:
1713      RADEON_STATECHANGE( rmesa, ctx );
1714      if ( state ) {
1715	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_PATTERN_ENABLE;
1716      } else {
1717	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1718      }
1719      break;
1720
1721   case GL_COLOR_LOGIC_OP:
1722      RADEON_STATECHANGE( rmesa, ctx );
1723      if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1724	    && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) {
1725	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
1726      } else {
1727	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1728      }
1729      break;
1730
1731   case GL_NORMALIZE:
1732      RADEON_STATECHANGE( rmesa, tcl );
1733      if ( state ) {
1734	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_NORMALIZE_NORMALS;
1735      } else {
1736	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1737      }
1738      break;
1739
1740   case GL_POLYGON_OFFSET_POINT:
1741      RADEON_STATECHANGE( rmesa, set );
1742      if ( state ) {
1743	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_POINT;
1744      } else {
1745	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1746      }
1747      break;
1748
1749   case GL_POLYGON_OFFSET_LINE:
1750      RADEON_STATECHANGE( rmesa, set );
1751      if ( state ) {
1752	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_LINE;
1753      } else {
1754	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1755      }
1756      break;
1757
1758   case GL_POLYGON_OFFSET_FILL:
1759      RADEON_STATECHANGE( rmesa, set );
1760      if ( state ) {
1761	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_TRI;
1762      } else {
1763	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1764      }
1765      break;
1766
1767   case GL_POLYGON_SMOOTH:
1768      RADEON_STATECHANGE( rmesa, ctx );
1769      if ( state ) {
1770	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_POLY;
1771      } else {
1772	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1773      }
1774      break;
1775
1776   case GL_POLYGON_STIPPLE:
1777      RADEON_STATECHANGE(rmesa, ctx );
1778      if ( state ) {
1779	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_STIPPLE_ENABLE;
1780      } else {
1781	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1782      }
1783      break;
1784
1785   case GL_RESCALE_NORMAL_EXT: {
1786      GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1787      RADEON_STATECHANGE( rmesa, tcl );
1788      if ( tmp ) {
1789	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
1790      } else {
1791	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1792      }
1793      break;
1794   }
1795
1796   case GL_SCISSOR_TEST:
1797      radeon_firevertices(&rmesa->radeon);
1798      rmesa->radeon.state.scissor.enabled = state;
1799      radeonUpdateScissor( ctx );
1800      break;
1801
1802   case GL_STENCIL_TEST:
1803      if ( rmesa->radeon.state.stencil.hwBuffer ) {
1804	 RADEON_STATECHANGE( rmesa, ctx );
1805	 if ( state ) {
1806	    rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_STENCIL_ENABLE;
1807	 } else {
1808	    rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1809	 }
1810      } else {
1811	 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1812      }
1813      break;
1814
1815   case GL_TEXTURE_GEN_Q:
1816   case GL_TEXTURE_GEN_R:
1817   case GL_TEXTURE_GEN_S:
1818   case GL_TEXTURE_GEN_T:
1819      /* Picked up in radeonUpdateTextureState.
1820       */
1821      rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1822      break;
1823
1824   case GL_COLOR_SUM_EXT:
1825      radeonUpdateSpecular ( ctx );
1826      break;
1827
1828   default:
1829      return;
1830   }
1831}
1832
1833
1834static void radeonLightingSpaceChange( GLcontext *ctx )
1835{
1836   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1837   GLboolean tmp;
1838   RADEON_STATECHANGE( rmesa, tcl );
1839
1840   if (RADEON_DEBUG & DEBUG_STATE)
1841      fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1842	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1843
1844   if (ctx->_NeedEyeCoords)
1845      tmp = ctx->Transform.RescaleNormals;
1846   else
1847      tmp = !ctx->Transform.RescaleNormals;
1848
1849   if ( tmp ) {
1850      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
1851   } else {
1852      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1853   }
1854
1855   if (RADEON_DEBUG & DEBUG_STATE)
1856      fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1857	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1858}
1859
1860/* =============================================================
1861 * Deferred state management - matrices, textures, other?
1862 */
1863
1864
1865void radeonUploadTexMatrix( r100ContextPtr rmesa,
1866			    int unit, GLboolean swapcols )
1867{
1868/* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1869   vector looks like this probably: (s t r|q 0) (not sure if the last coord
1870   is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1871   texgen generates all 4 coords, at least tests with projtex indicated that.
1872   So: if we need the q coord in the end (solely determined by the texture
1873   target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1874   Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1875   column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
1876   will get submitted in the "wrong", i.e. 3rd, slot.
1877   If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1878   size and using the texture matrix to swap the r and q coords around (ut2k3
1879   does exactly that), so we don't need the 3rd / 4th column swap - still need
1880   the 3rd / 4th row swap of course. This will potentially break for apps which
1881   use TexCoord3x just for fun. Additionally, it will never work if an app uses
1882   an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1883   the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1884   incredibly hard to detect so we can't just fallback in such a case. Assume
1885   it never happens... - rs
1886*/
1887
1888   int idx = TEXMAT_0 + unit;
1889   float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1890   int i;
1891   struct gl_texture_unit tUnit = rmesa->radeon.glCtx->Texture.Unit[unit];
1892   GLfloat *src = rmesa->tmpmat[unit].m;
1893
1894   rmesa->TexMatColSwap &= ~(1 << unit);
1895   if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
1896      if (swapcols) {
1897	 rmesa->TexMatColSwap |= 1 << unit;
1898	 /* attention some elems are swapped 2 times! */
1899	 *dest++ = src[0];
1900	 *dest++ = src[4];
1901	 *dest++ = src[12];
1902	 *dest++ = src[8];
1903	 *dest++ = src[1];
1904	 *dest++ = src[5];
1905	 *dest++ = src[13];
1906	 *dest++ = src[9];
1907	 *dest++ = src[2];
1908	 *dest++ = src[6];
1909	 *dest++ = src[15];
1910	 *dest++ = src[11];
1911	 /* those last 4 are probably never used */
1912	 *dest++ = src[3];
1913	 *dest++ = src[7];
1914	 *dest++ = src[14];
1915	 *dest++ = src[10];
1916      }
1917      else {
1918	 for (i = 0; i < 2; i++) {
1919	    *dest++ = src[i];
1920	    *dest++ = src[i+4];
1921	    *dest++ = src[i+8];
1922	    *dest++ = src[i+12];
1923	 }
1924	 for (i = 3; i >= 2; i--) {
1925	    *dest++ = src[i];
1926	    *dest++ = src[i+4];
1927	    *dest++ = src[i+8];
1928	    *dest++ = src[i+12];
1929	 }
1930      }
1931   }
1932   else {
1933      for (i = 0 ; i < 4 ; i++) {
1934	 *dest++ = src[i];
1935	 *dest++ = src[i+4];
1936	 *dest++ = src[i+8];
1937	 *dest++ = src[i+12];
1938      }
1939   }
1940
1941   RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1942}
1943
1944
1945static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1946{
1947   float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1948   int i;
1949
1950
1951   for (i = 0 ; i < 4 ; i++) {
1952      *dest++ = src[i];
1953      *dest++ = src[i+4];
1954      *dest++ = src[i+8];
1955      *dest++ = src[i+12];
1956   }
1957
1958   RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1959}
1960
1961static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1962{
1963   float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1964   memcpy(dest, src, 16*sizeof(float));
1965   RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1966}
1967
1968
1969static void update_texturematrix( GLcontext *ctx )
1970{
1971   r100ContextPtr rmesa = R100_CONTEXT( ctx );
1972   GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
1973   GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
1974   int unit;
1975   GLuint texMatEnabled = 0;
1976   rmesa->NeedTexMatrix = 0;
1977   rmesa->TexMatColSwap = 0;
1978
1979   for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
1980      if (ctx->Texture.Unit[unit]._ReallyEnabled) {
1981	 GLboolean needMatrix = GL_FALSE;
1982	 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
1983	    needMatrix = GL_TRUE;
1984	    texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
1985			      RADEON_TEXMAT_0_ENABLE) << unit;
1986
1987	    if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1988	       /* Need to preconcatenate any active texgen
1989	        * obj/eyeplane matrices:
1990	        */
1991	       _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
1992				     ctx->TextureMatrixStack[unit].Top,
1993				     &rmesa->TexGenMatrix[unit] );
1994	    }
1995	    else {
1996	       _math_matrix_copy( &rmesa->tmpmat[unit],
1997		  ctx->TextureMatrixStack[unit].Top );
1998	    }
1999	 }
2000	 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2001	    _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
2002	    needMatrix = GL_TRUE;
2003	 }
2004	 if (needMatrix) {
2005	    rmesa->NeedTexMatrix |= 1 << unit;
2006	    radeonUploadTexMatrix( rmesa, unit,
2007			!ctx->Texture.Unit[unit].TexGenEnabled );
2008	 }
2009      }
2010   }
2011
2012   tpc = (texMatEnabled | rmesa->TexGenEnabled);
2013
2014   /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2015   vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
2016	   (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
2017	   (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
2018
2019   vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
2020	 (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
2021      ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
2022	 (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
2023      ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
2024	 (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
2025
2026   if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
2027       vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
2028
2029      RADEON_STATECHANGE(rmesa, tcl);
2030      rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
2031      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
2032   }
2033}
2034
2035
2036void radeonValidateState( GLcontext *ctx )
2037{
2038   r100ContextPtr rmesa = R100_CONTEXT(ctx);
2039   GLuint new_state = rmesa->radeon.NewGLState;
2040
2041   if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
2042     _mesa_update_framebuffer(ctx);
2043     /* this updates the DrawBuffer's Width/Height if it's a FBO */
2044     _mesa_update_draw_buffer_bounds(ctx);
2045     RADEON_STATECHANGE(rmesa, ctx);
2046   }
2047
2048   if (new_state & _NEW_TEXTURE) {
2049      radeonUpdateTextureState( ctx );
2050      new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2051   }
2052
2053   /* Need an event driven matrix update?
2054    */
2055   if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2056      upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2057
2058   /* Need these for lighting (shouldn't upload otherwise)
2059    */
2060   if (new_state & (_NEW_MODELVIEW)) {
2061      upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2062      upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2063   }
2064
2065   /* Does this need to be triggered on eg. modelview for
2066    * texgen-derived objplane/eyeplane matrices?
2067    */
2068   if (new_state & _NEW_TEXTURE_MATRIX) {
2069      update_texturematrix( ctx );
2070   }
2071
2072   if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2073      update_light( ctx );
2074   }
2075
2076   /* emit all active clip planes if projection matrix changes.
2077    */
2078   if (new_state & (_NEW_PROJECTION)) {
2079      if (ctx->Transform.ClipPlanesEnabled)
2080	 radeonUpdateClipPlanes( ctx );
2081   }
2082
2083
2084   rmesa->radeon.NewGLState = 0;
2085}
2086
2087
2088static void radeonInvalidateState( GLcontext *ctx, GLuint new_state )
2089{
2090   _swrast_InvalidateState( ctx, new_state );
2091   _swsetup_InvalidateState( ctx, new_state );
2092   _vbo_InvalidateState( ctx, new_state );
2093   _tnl_InvalidateState( ctx, new_state );
2094   _ae_invalidate_state( ctx, new_state );
2095   R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2096}
2097
2098
2099/* A hack.  Need a faster way to find this out.
2100 */
2101static GLboolean check_material( GLcontext *ctx )
2102{
2103   TNLcontext *tnl = TNL_CONTEXT(ctx);
2104   GLint i;
2105
2106   for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2107	i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2108	i++)
2109      if (tnl->vb.AttribPtr[i] &&
2110	  tnl->vb.AttribPtr[i]->stride)
2111	 return GL_TRUE;
2112
2113   return GL_FALSE;
2114}
2115
2116
2117static void radeonWrapRunPipeline( GLcontext *ctx )
2118{
2119   r100ContextPtr rmesa = R100_CONTEXT(ctx);
2120   GLboolean has_material;
2121
2122   if (0)
2123      fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2124
2125   /* Validate state:
2126    */
2127   if (rmesa->radeon.NewGLState)
2128      radeonValidateState( ctx );
2129
2130   has_material = (ctx->Light.Enabled && check_material( ctx ));
2131
2132   if (has_material) {
2133      TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2134   }
2135
2136   /* Run the pipeline.
2137    */
2138   _tnl_run_pipeline( ctx );
2139
2140   if (has_material) {
2141      TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2142   }
2143}
2144
2145
2146/* Initialize the driver's state functions.
2147 * Many of the ctx->Driver functions might have been initialized to
2148 * software defaults in the earlier _mesa_init_driver_functions() call.
2149 */
2150void radeonInitStateFuncs( GLcontext *ctx )
2151{
2152   ctx->Driver.UpdateState		= radeonInvalidateState;
2153   ctx->Driver.LightingSpaceChange      = radeonLightingSpaceChange;
2154
2155   ctx->Driver.DrawBuffer		= radeonDrawBuffer;
2156   ctx->Driver.ReadBuffer		= radeonReadBuffer;
2157
2158   ctx->Driver.AlphaFunc		= radeonAlphaFunc;
2159   ctx->Driver.BlendEquationSeparate	= radeonBlendEquationSeparate;
2160   ctx->Driver.BlendFuncSeparate	= radeonBlendFuncSeparate;
2161   ctx->Driver.ClearColor		= radeonClearColor;
2162   ctx->Driver.ClearDepth		= radeonClearDepth;
2163   ctx->Driver.ClearIndex		= NULL;
2164   ctx->Driver.ClearStencil		= radeonClearStencil;
2165   ctx->Driver.ClipPlane		= radeonClipPlane;
2166   ctx->Driver.ColorMask		= radeonColorMask;
2167   ctx->Driver.CullFace			= radeonCullFace;
2168   ctx->Driver.DepthFunc		= radeonDepthFunc;
2169   ctx->Driver.DepthMask		= radeonDepthMask;
2170   ctx->Driver.DepthRange		= radeonDepthRange;
2171   ctx->Driver.Enable			= radeonEnable;
2172   ctx->Driver.Fogfv			= radeonFogfv;
2173   ctx->Driver.FrontFace		= radeonFrontFace;
2174   ctx->Driver.Hint			= NULL;
2175   ctx->Driver.IndexMask		= NULL;
2176   ctx->Driver.LightModelfv		= radeonLightModelfv;
2177   ctx->Driver.Lightfv			= radeonLightfv;
2178   ctx->Driver.LineStipple              = radeonLineStipple;
2179   ctx->Driver.LineWidth                = radeonLineWidth;
2180   ctx->Driver.LogicOpcode		= radeonLogicOpCode;
2181   ctx->Driver.PolygonMode		= radeonPolygonMode;
2182   ctx->Driver.PolygonOffset		= radeonPolygonOffset;
2183   ctx->Driver.PolygonStipple		= radeonPolygonStipple;
2184   ctx->Driver.RenderMode		= radeonRenderMode;
2185   ctx->Driver.Scissor			= radeonScissor;
2186   ctx->Driver.ShadeModel		= radeonShadeModel;
2187   ctx->Driver.StencilFuncSeparate	= radeonStencilFuncSeparate;
2188   ctx->Driver.StencilMaskSeparate	= radeonStencilMaskSeparate;
2189   ctx->Driver.StencilOpSeparate	= radeonStencilOpSeparate;
2190   ctx->Driver.Viewport			= radeonViewport;
2191
2192   TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2193   TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2194}
2195