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