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