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