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