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