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