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