radeon_state.c revision e0ed951e1361e54ffd8e9c56fbcc2027c0c4bd24
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 radeonClearColor( struct gl_context *ctx,
1462                              const union gl_color_union color )
1463{
1464   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1465   GLubyte c[4];
1466   struct radeon_renderbuffer *rrb;
1467
1468   rrb = radeon_get_colorbuffer(&rmesa->radeon);
1469   if (!rrb)
1470     return;
1471
1472   _mesa_unclamped_float_rgba_to_ubyte(c, color.f);
1473   rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
1474					       c[0], c[1], c[2], c[3] );
1475}
1476
1477
1478static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
1479{
1480   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1481   FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1482}
1483
1484
1485static GLuint radeon_rop_tab[] = {
1486   RADEON_ROP_CLEAR,
1487   RADEON_ROP_AND,
1488   RADEON_ROP_AND_REVERSE,
1489   RADEON_ROP_COPY,
1490   RADEON_ROP_AND_INVERTED,
1491   RADEON_ROP_NOOP,
1492   RADEON_ROP_XOR,
1493   RADEON_ROP_OR,
1494   RADEON_ROP_NOR,
1495   RADEON_ROP_EQUIV,
1496   RADEON_ROP_INVERT,
1497   RADEON_ROP_OR_REVERSE,
1498   RADEON_ROP_COPY_INVERTED,
1499   RADEON_ROP_OR_INVERTED,
1500   RADEON_ROP_NAND,
1501   RADEON_ROP_SET,
1502};
1503
1504static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode )
1505{
1506   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1507   GLuint rop = (GLuint)opcode - GL_CLEAR;
1508
1509   ASSERT( rop < 16 );
1510
1511   RADEON_STATECHANGE( rmesa, msk );
1512   rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1513}
1514
1515/* =============================================================
1516 * State enable/disable
1517 */
1518
1519static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
1520{
1521   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1522   GLuint p, flag;
1523
1524   if ( RADEON_DEBUG & RADEON_STATE )
1525      fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1526	       _mesa_lookup_enum_by_nr( cap ),
1527	       state ? "GL_TRUE" : "GL_FALSE" );
1528
1529   switch ( cap ) {
1530      /* Fast track this one...
1531       */
1532   case GL_TEXTURE_1D:
1533   case GL_TEXTURE_2D:
1534   case GL_TEXTURE_3D:
1535      break;
1536
1537   case GL_ALPHA_TEST:
1538      RADEON_STATECHANGE( rmesa, ctx );
1539      if (state) {
1540	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1541      } else {
1542	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1543      }
1544      break;
1545
1546   case GL_BLEND:
1547      RADEON_STATECHANGE( rmesa, ctx );
1548      if (state) {
1549	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ALPHA_BLEND_ENABLE;
1550      } else {
1551	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1552      }
1553      if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1554	    && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1555	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
1556      } else {
1557	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1558      }
1559
1560      /* Catch a possible fallback:
1561       */
1562      if (state) {
1563	 ctx->Driver.BlendEquationSeparate( ctx,
1564					    ctx->Color.Blend[0].EquationRGB,
1565					    ctx->Color.Blend[0].EquationA );
1566	 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
1567					ctx->Color.Blend[0].DstRGB,
1568					ctx->Color.Blend[0].SrcA,
1569					ctx->Color.Blend[0].DstA );
1570      }
1571      else {
1572	 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1573	 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1574      }
1575      break;
1576
1577   case GL_CLIP_PLANE0:
1578   case GL_CLIP_PLANE1:
1579   case GL_CLIP_PLANE2:
1580   case GL_CLIP_PLANE3:
1581   case GL_CLIP_PLANE4:
1582   case GL_CLIP_PLANE5:
1583      p = cap-GL_CLIP_PLANE0;
1584      RADEON_STATECHANGE( rmesa, tcl );
1585      if (state) {
1586	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1587	 radeonClipPlane( ctx, cap, NULL );
1588      }
1589      else {
1590	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1591      }
1592      break;
1593
1594   case GL_COLOR_MATERIAL:
1595      radeonColorMaterial( ctx, 0, 0 );
1596      radeonUpdateMaterial( ctx );
1597      break;
1598
1599   case GL_CULL_FACE:
1600      radeonCullFace( ctx, 0 );
1601      break;
1602
1603   case GL_DEPTH_TEST:
1604      RADEON_STATECHANGE(rmesa, ctx );
1605      if ( state ) {
1606	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_Z_ENABLE;
1607      } else {
1608	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1609      }
1610      break;
1611
1612   case GL_DITHER:
1613      RADEON_STATECHANGE(rmesa, ctx );
1614      if ( state ) {
1615	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_DITHER_ENABLE;
1616	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1617      } else {
1618	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1619	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  rmesa->radeon.state.color.roundEnable;
1620      }
1621      break;
1622
1623   case GL_FOG:
1624      RADEON_STATECHANGE(rmesa, ctx );
1625      if ( state ) {
1626	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1627	 radeonFogfv( ctx, GL_FOG_MODE, NULL );
1628      } else {
1629	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1630	 RADEON_STATECHANGE(rmesa, tcl);
1631	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1632      }
1633      radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1634      _mesa_allow_light_in_model( ctx, !state );
1635      break;
1636
1637   case GL_LIGHT0:
1638   case GL_LIGHT1:
1639   case GL_LIGHT2:
1640   case GL_LIGHT3:
1641   case GL_LIGHT4:
1642   case GL_LIGHT5:
1643   case GL_LIGHT6:
1644   case GL_LIGHT7:
1645      RADEON_STATECHANGE(rmesa, tcl);
1646      p = cap - GL_LIGHT0;
1647      if (p&1)
1648	 flag = (RADEON_LIGHT_1_ENABLE |
1649		 RADEON_LIGHT_1_ENABLE_AMBIENT |
1650		 RADEON_LIGHT_1_ENABLE_SPECULAR);
1651      else
1652	 flag = (RADEON_LIGHT_0_ENABLE |
1653		 RADEON_LIGHT_0_ENABLE_AMBIENT |
1654		 RADEON_LIGHT_0_ENABLE_SPECULAR);
1655
1656      if (state)
1657	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1658      else
1659	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1660
1661      /*
1662       */
1663      update_light_colors( ctx, p );
1664      break;
1665
1666   case GL_LIGHTING:
1667      RADEON_STATECHANGE(rmesa, tcl);
1668      radeonUpdateSpecular(ctx);
1669      check_twoside_fallback( ctx );
1670      break;
1671
1672   case GL_LINE_SMOOTH:
1673      RADEON_STATECHANGE( rmesa, ctx );
1674      if ( state ) {
1675	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_LINE;
1676      } else {
1677	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1678      }
1679      break;
1680
1681   case GL_LINE_STIPPLE:
1682      RADEON_STATECHANGE( rmesa, ctx );
1683      if ( state ) {
1684	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_PATTERN_ENABLE;
1685      } else {
1686	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1687      }
1688      break;
1689
1690   case GL_COLOR_LOGIC_OP:
1691      RADEON_STATECHANGE( rmesa, ctx );
1692      if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1693	    && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1694	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
1695      } else {
1696	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1697      }
1698      break;
1699
1700   case GL_NORMALIZE:
1701      RADEON_STATECHANGE( rmesa, tcl );
1702      if ( state ) {
1703	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_NORMALIZE_NORMALS;
1704      } else {
1705	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1706      }
1707      break;
1708
1709   case GL_POLYGON_OFFSET_POINT:
1710      RADEON_STATECHANGE( rmesa, set );
1711      if ( state ) {
1712	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_POINT;
1713      } else {
1714	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1715      }
1716      break;
1717
1718   case GL_POLYGON_OFFSET_LINE:
1719      RADEON_STATECHANGE( rmesa, set );
1720      if ( state ) {
1721	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_LINE;
1722      } else {
1723	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1724      }
1725      break;
1726
1727   case GL_POLYGON_OFFSET_FILL:
1728      RADEON_STATECHANGE( rmesa, set );
1729      if ( state ) {
1730	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_TRI;
1731      } else {
1732	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1733      }
1734      break;
1735
1736   case GL_POLYGON_SMOOTH:
1737      RADEON_STATECHANGE( rmesa, ctx );
1738      if ( state ) {
1739	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_POLY;
1740      } else {
1741	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1742      }
1743      break;
1744
1745   case GL_POLYGON_STIPPLE:
1746      RADEON_STATECHANGE(rmesa, ctx );
1747      if ( state ) {
1748	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_STIPPLE_ENABLE;
1749      } else {
1750	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1751      }
1752      break;
1753
1754   case GL_RESCALE_NORMAL_EXT: {
1755      GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1756      RADEON_STATECHANGE( rmesa, tcl );
1757      if ( tmp ) {
1758	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
1759      } else {
1760	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1761      }
1762      break;
1763   }
1764
1765   case GL_SCISSOR_TEST:
1766      radeon_firevertices(&rmesa->radeon);
1767      rmesa->radeon.state.scissor.enabled = state;
1768      radeonUpdateScissor( ctx );
1769      break;
1770
1771   case GL_STENCIL_TEST:
1772      {
1773	 GLboolean hw_stencil = GL_FALSE;
1774	 if (ctx->DrawBuffer) {
1775	    struct radeon_renderbuffer *rrbStencil
1776	       = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1777	    hw_stencil = (rrbStencil && rrbStencil->bo);
1778	 }
1779
1780	 if (hw_stencil) {
1781	    RADEON_STATECHANGE( rmesa, ctx );
1782	    if ( state ) {
1783	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_STENCIL_ENABLE;
1784	    } else {
1785	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1786	    }
1787	 } else {
1788	    FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1789	 }
1790      }
1791      break;
1792
1793   case GL_TEXTURE_GEN_Q:
1794   case GL_TEXTURE_GEN_R:
1795   case GL_TEXTURE_GEN_S:
1796   case GL_TEXTURE_GEN_T:
1797      /* Picked up in radeonUpdateTextureState.
1798       */
1799      rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1800      break;
1801
1802   case GL_COLOR_SUM_EXT:
1803      radeonUpdateSpecular ( ctx );
1804      break;
1805
1806   default:
1807      return;
1808   }
1809}
1810
1811
1812static void radeonLightingSpaceChange( struct gl_context *ctx )
1813{
1814   r100ContextPtr rmesa = R100_CONTEXT(ctx);
1815   GLboolean tmp;
1816   RADEON_STATECHANGE( rmesa, tcl );
1817
1818   if (RADEON_DEBUG & RADEON_STATE)
1819      fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1820	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1821
1822   if (ctx->_NeedEyeCoords)
1823      tmp = ctx->Transform.RescaleNormals;
1824   else
1825      tmp = !ctx->Transform.RescaleNormals;
1826
1827   if ( tmp ) {
1828      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
1829   } else {
1830      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1831   }
1832
1833   if (RADEON_DEBUG & RADEON_STATE)
1834      fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1835	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1836}
1837
1838/* =============================================================
1839 * Deferred state management - matrices, textures, other?
1840 */
1841
1842
1843void radeonUploadTexMatrix( r100ContextPtr rmesa,
1844			    int unit, GLboolean swapcols )
1845{
1846/* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1847   vector looks like this probably: (s t r|q 0) (not sure if the last coord
1848   is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1849   texgen generates all 4 coords, at least tests with projtex indicated that.
1850   So: if we need the q coord in the end (solely determined by the texture
1851   target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1852   Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1853   column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1854   will get submitted in the "wrong", i.e. 3rd, slot.
1855   If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1856   size and using the texture matrix to swap the r and q coords around (ut2k3
1857   does exactly that), so we don't need the 3rd / 4th column swap - still need
1858   the 3rd / 4th row swap of course. This will potentially break for apps which
1859   use TexCoord3x just for fun. Additionally, it will never work if an app uses
1860   an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1861   the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1862   incredibly hard to detect so we can't just fallback in such a case. Assume
1863   it never happens... - rs
1864*/
1865
1866   int idx = TEXMAT_0 + unit;
1867   float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1868   int i;
1869   struct gl_texture_unit tUnit = rmesa->radeon.glCtx->Texture.Unit[unit];
1870   GLfloat *src = rmesa->tmpmat[unit].m;
1871
1872   rmesa->TexMatColSwap &= ~(1 << unit);
1873   if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
1874      if (swapcols) {
1875	 rmesa->TexMatColSwap |= 1 << unit;
1876	 /* attention some elems are swapped 2 times! */
1877	 *dest++ = src[0];
1878	 *dest++ = src[4];
1879	 *dest++ = src[12];
1880	 *dest++ = src[8];
1881	 *dest++ = src[1];
1882	 *dest++ = src[5];
1883	 *dest++ = src[13];
1884	 *dest++ = src[9];
1885	 *dest++ = src[2];
1886	 *dest++ = src[6];
1887	 *dest++ = src[15];
1888	 *dest++ = src[11];
1889	 /* those last 4 are probably never used */
1890	 *dest++ = src[3];
1891	 *dest++ = src[7];
1892	 *dest++ = src[14];
1893	 *dest++ = src[10];
1894      }
1895      else {
1896	 for (i = 0; i < 2; i++) {
1897	    *dest++ = src[i];
1898	    *dest++ = src[i+4];
1899	    *dest++ = src[i+8];
1900	    *dest++ = src[i+12];
1901	 }
1902	 for (i = 3; i >= 2; i--) {
1903	    *dest++ = src[i];
1904	    *dest++ = src[i+4];
1905	    *dest++ = src[i+8];
1906	    *dest++ = src[i+12];
1907	 }
1908      }
1909   }
1910   else {
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
1919   RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1920}
1921
1922
1923static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1924{
1925   float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1926   int i;
1927
1928
1929   for (i = 0 ; i < 4 ; i++) {
1930      *dest++ = src[i];
1931      *dest++ = src[i+4];
1932      *dest++ = src[i+8];
1933      *dest++ = src[i+12];
1934   }
1935
1936   RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1937}
1938
1939static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1940{
1941   float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1942   memcpy(dest, src, 16*sizeof(float));
1943   RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1944}
1945
1946
1947static void update_texturematrix( struct gl_context *ctx )
1948{
1949   r100ContextPtr rmesa = R100_CONTEXT( ctx );
1950   GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
1951   GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
1952   int unit;
1953   GLuint texMatEnabled = 0;
1954   rmesa->NeedTexMatrix = 0;
1955   rmesa->TexMatColSwap = 0;
1956
1957   for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
1958      if (ctx->Texture.Unit[unit]._ReallyEnabled) {
1959	 GLboolean needMatrix = GL_FALSE;
1960	 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
1961	    needMatrix = GL_TRUE;
1962	    texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
1963			      RADEON_TEXMAT_0_ENABLE) << unit;
1964
1965	    if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1966	       /* Need to preconcatenate any active texgen
1967	        * obj/eyeplane matrices:
1968	        */
1969	       _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
1970				     ctx->TextureMatrixStack[unit].Top,
1971				     &rmesa->TexGenMatrix[unit] );
1972	    }
1973	    else {
1974	       _math_matrix_copy( &rmesa->tmpmat[unit],
1975		  ctx->TextureMatrixStack[unit].Top );
1976	    }
1977	 }
1978	 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1979	    _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
1980	    needMatrix = GL_TRUE;
1981	 }
1982	 if (needMatrix) {
1983	    rmesa->NeedTexMatrix |= 1 << unit;
1984	    radeonUploadTexMatrix( rmesa, unit,
1985			!ctx->Texture.Unit[unit].TexGenEnabled );
1986	 }
1987      }
1988   }
1989
1990   tpc = (texMatEnabled | rmesa->TexGenEnabled);
1991
1992   /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1993   vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
1994	   (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
1995	   (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
1996
1997   vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
1998	 (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
1999      ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
2000	 (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
2001      ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
2002	 (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
2003
2004   if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
2005       vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
2006
2007      RADEON_STATECHANGE(rmesa, tcl);
2008      rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
2009      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
2010   }
2011}
2012
2013static GLboolean r100ValidateBuffers(struct gl_context *ctx)
2014{
2015   r100ContextPtr rmesa = R100_CONTEXT(ctx);
2016   struct radeon_renderbuffer *rrb;
2017   int i, ret;
2018
2019   radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2020
2021   rrb = radeon_get_colorbuffer(&rmesa->radeon);
2022   /* color buffer */
2023   if (rrb && rrb->bo) {
2024     radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2025				       0, RADEON_GEM_DOMAIN_VRAM);
2026   }
2027
2028   /* depth buffer */
2029   rrb = radeon_get_depthbuffer(&rmesa->radeon);
2030   /* color buffer */
2031   if (rrb && rrb->bo) {
2032     radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2033				       0, RADEON_GEM_DOMAIN_VRAM);
2034   }
2035
2036   for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
2037      radeonTexObj *t;
2038
2039      if (!ctx->Texture.Unit[i]._ReallyEnabled)
2040	 continue;
2041
2042      t = rmesa->state.texture.unit[i].texobj;
2043
2044      if (!t)
2045	 continue;
2046      if (t->image_override && t->bo)
2047	radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2048			   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2049      else if (t->mt->bo)
2050	radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2051			   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2052   }
2053
2054   ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
2055   if (ret)
2056       return GL_FALSE;
2057   return GL_TRUE;
2058}
2059
2060GLboolean radeonValidateState( struct gl_context *ctx )
2061{
2062   r100ContextPtr rmesa = R100_CONTEXT(ctx);
2063   GLuint new_state = rmesa->radeon.NewGLState;
2064
2065   if (new_state & _NEW_BUFFERS) {
2066     _mesa_update_framebuffer(ctx);
2067     /* this updates the DrawBuffer's Width/Height if it's a FBO */
2068     _mesa_update_draw_buffer_bounds(ctx);
2069     RADEON_STATECHANGE(rmesa, ctx);
2070   }
2071
2072   if (new_state & _NEW_TEXTURE) {
2073      radeonUpdateTextureState( ctx );
2074      new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2075   }
2076
2077   /* we need to do a space check here */
2078   if (!r100ValidateBuffers(ctx))
2079     return GL_FALSE;
2080
2081   /* Need an event driven matrix update?
2082    */
2083   if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2084      upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2085
2086   /* Need these for lighting (shouldn't upload otherwise)
2087    */
2088   if (new_state & (_NEW_MODELVIEW)) {
2089      upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2090      upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2091   }
2092
2093   /* Does this need to be triggered on eg. modelview for
2094    * texgen-derived objplane/eyeplane matrices?
2095    */
2096   if (new_state & _NEW_TEXTURE_MATRIX) {
2097      update_texturematrix( ctx );
2098   }
2099
2100   if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2101      update_light( ctx );
2102   }
2103
2104   /* emit all active clip planes if projection matrix changes.
2105    */
2106   if (new_state & (_NEW_PROJECTION)) {
2107      if (ctx->Transform.ClipPlanesEnabled)
2108	 radeonUpdateClipPlanes( ctx );
2109   }
2110
2111
2112   rmesa->radeon.NewGLState = 0;
2113
2114   return GL_TRUE;
2115}
2116
2117
2118static void radeonInvalidateState( struct gl_context *ctx, GLuint new_state )
2119{
2120   _swrast_InvalidateState( ctx, new_state );
2121   _swsetup_InvalidateState( ctx, new_state );
2122   _vbo_InvalidateState( ctx, new_state );
2123   _tnl_InvalidateState( ctx, new_state );
2124   _ae_invalidate_state( ctx, new_state );
2125   R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2126}
2127
2128
2129/* A hack.  Need a faster way to find this out.
2130 */
2131static GLboolean check_material( struct gl_context *ctx )
2132{
2133   TNLcontext *tnl = TNL_CONTEXT(ctx);
2134   GLint i;
2135
2136   for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2137	i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2138	i++)
2139      if (tnl->vb.AttribPtr[i] &&
2140	  tnl->vb.AttribPtr[i]->stride)
2141	 return GL_TRUE;
2142
2143   return GL_FALSE;
2144}
2145
2146
2147static void radeonWrapRunPipeline( struct gl_context *ctx )
2148{
2149   r100ContextPtr rmesa = R100_CONTEXT(ctx);
2150   GLboolean has_material;
2151
2152   if (0)
2153      fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2154
2155   /* Validate state:
2156    */
2157   if (rmesa->radeon.NewGLState)
2158      if (!radeonValidateState( ctx ))
2159	 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2160
2161   has_material = (ctx->Light.Enabled && check_material( ctx ));
2162
2163   if (has_material) {
2164      TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2165   }
2166
2167   /* Run the pipeline.
2168    */
2169   _tnl_run_pipeline( ctx );
2170
2171   if (has_material) {
2172      TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2173   }
2174}
2175
2176static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2177{
2178   r100ContextPtr r100 = R100_CONTEXT(ctx);
2179   GLint i;
2180
2181   radeon_firevertices(&r100->radeon);
2182
2183   RADEON_STATECHANGE(r100, stp);
2184
2185   /* Must flip pattern upside down.
2186    */
2187   for ( i = 31 ; i >= 0; i--) {
2188     r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2189   }
2190}
2191
2192
2193/* Initialize the driver's state functions.
2194 * Many of the ctx->Driver functions might have been initialized to
2195 * software defaults in the earlier _mesa_init_driver_functions() call.
2196 */
2197void radeonInitStateFuncs( struct gl_context *ctx )
2198{
2199   ctx->Driver.UpdateState		= radeonInvalidateState;
2200   ctx->Driver.LightingSpaceChange      = radeonLightingSpaceChange;
2201
2202   ctx->Driver.DrawBuffer		= radeonDrawBuffer;
2203   ctx->Driver.ReadBuffer		= radeonReadBuffer;
2204   ctx->Driver.CopyPixels               = _mesa_meta_CopyPixels;
2205   ctx->Driver.DrawPixels               = _mesa_meta_DrawPixels;
2206   ctx->Driver.ReadPixels               = radeonReadPixels;
2207
2208   ctx->Driver.AlphaFunc		= radeonAlphaFunc;
2209   ctx->Driver.BlendEquationSeparate	= radeonBlendEquationSeparate;
2210   ctx->Driver.BlendFuncSeparate	= radeonBlendFuncSeparate;
2211   ctx->Driver.ClearColor		= radeonClearColor;
2212   ctx->Driver.ClipPlane		= radeonClipPlane;
2213   ctx->Driver.ColorMask		= radeonColorMask;
2214   ctx->Driver.CullFace			= radeonCullFace;
2215   ctx->Driver.DepthFunc		= radeonDepthFunc;
2216   ctx->Driver.DepthMask		= radeonDepthMask;
2217   ctx->Driver.DepthRange		= radeonDepthRange;
2218   ctx->Driver.Enable			= radeonEnable;
2219   ctx->Driver.Fogfv			= radeonFogfv;
2220   ctx->Driver.FrontFace		= radeonFrontFace;
2221   ctx->Driver.Hint			= NULL;
2222   ctx->Driver.LightModelfv		= radeonLightModelfv;
2223   ctx->Driver.Lightfv			= radeonLightfv;
2224   ctx->Driver.LineStipple              = radeonLineStipple;
2225   ctx->Driver.LineWidth                = radeonLineWidth;
2226   ctx->Driver.LogicOpcode		= radeonLogicOpCode;
2227   ctx->Driver.PolygonMode		= radeonPolygonMode;
2228   ctx->Driver.PolygonOffset		= radeonPolygonOffset;
2229   ctx->Driver.PolygonStipple		= radeonPolygonStipple;
2230   ctx->Driver.RenderMode		= radeonRenderMode;
2231   ctx->Driver.Scissor			= radeonScissor;
2232   ctx->Driver.ShadeModel		= radeonShadeModel;
2233   ctx->Driver.StencilFuncSeparate	= radeonStencilFuncSeparate;
2234   ctx->Driver.StencilMaskSeparate	= radeonStencilMaskSeparate;
2235   ctx->Driver.StencilOpSeparate	= radeonStencilOpSeparate;
2236   ctx->Driver.Viewport			= radeonViewport;
2237
2238   TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2239   TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2240}
2241