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