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