Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / r200 / r200_state.c
1 /**************************************************************************
2
3 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
4
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 /*
32  * Authors:
33  *   Keith Whitwell <keith@tungstengraphics.com>
34  */
35
36 #include "main/glheader.h"
37 #include "main/imports.h"
38 #include "main/api_arrayelt.h"
39 #include "main/enums.h"
40 #include "main/colormac.h"
41 #include "main/light.h"
42 #include "main/framebuffer.h"
43
44 #include "swrast/swrast.h"
45 #include "vbo/vbo.h"
46 #include "tnl/tnl.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "drivers/common/meta.h"
50
51 #include "radeon_common.h"
52 #include "radeon_mipmap_tree.h"
53 #include "r200_context.h"
54 #include "r200_ioctl.h"
55 #include "r200_state.h"
56 #include "r200_tcl.h"
57 #include "r200_tex.h"
58 #include "r200_swtcl.h"
59 #include "r200_vertprog.h"
60
61
62 /* =============================================================
63  * Alpha blending
64  */
65
66 static void r200AlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
67 {
68    r200ContextPtr rmesa = R200_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    R200_STATECHANGE( rmesa, ctx );
75
76    pp_misc &= ~(R200_ALPHA_TEST_OP_MASK | R200_REF_ALPHA_MASK);
77    pp_misc |= (refByte & R200_REF_ALPHA_MASK);
78
79    switch ( func ) {
80    case GL_NEVER:
81       pp_misc |= R200_ALPHA_TEST_FAIL;
82       break;
83    case GL_LESS:
84       pp_misc |= R200_ALPHA_TEST_LESS;
85       break;
86    case GL_EQUAL:
87       pp_misc |= R200_ALPHA_TEST_EQUAL;
88       break;
89    case GL_LEQUAL:
90       pp_misc |= R200_ALPHA_TEST_LEQUAL;
91       break;
92    case GL_GREATER:
93       pp_misc |= R200_ALPHA_TEST_GREATER;
94       break;
95    case GL_NOTEQUAL:
96       pp_misc |= R200_ALPHA_TEST_NEQUAL;
97       break;
98    case GL_GEQUAL:
99       pp_misc |= R200_ALPHA_TEST_GEQUAL;
100       break;
101    case GL_ALWAYS:
102       pp_misc |= R200_ALPHA_TEST_PASS;
103       break;
104    }
105
106    rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
107 }
108
109 static void r200BlendColor( struct gl_context *ctx, const GLfloat cf[4] )
110 {
111    GLubyte color[4];
112    r200ContextPtr rmesa = R200_CONTEXT(ctx);
113    R200_STATECHANGE( rmesa, ctx );
114    CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
115    CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
116    CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
117    CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
118    if (rmesa->radeon.radeonScreen->drmSupportsBlendColor)
119       rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] = radeonPackColor( 4, color[0], color[1], color[2], color[3] );
120 }
121
122 /**
123  * Calculate the hardware blend factor setting.  This same function is used
124  * for source and destination of both alpha and RGB.
125  *
126  * \returns
127  * The hardware register value for the specified blend factor.  This value
128  * will need to be shifted into the correct position for either source or
129  * destination factor.
130  *
131  * \todo
132  * Since the two cases where source and destination are handled differently
133  * are essentially error cases, they should never happen.  Determine if these
134  * cases can be removed.
135  */
136 static int blend_factor( GLenum factor, GLboolean is_src )
137 {
138    int func;
139
140    switch ( factor ) {
141    case GL_ZERO:
142       func = R200_BLEND_GL_ZERO;
143       break;
144    case GL_ONE:
145       func = R200_BLEND_GL_ONE;
146       break;
147    case GL_DST_COLOR:
148       func = R200_BLEND_GL_DST_COLOR;
149       break;
150    case GL_ONE_MINUS_DST_COLOR:
151       func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
152       break;
153    case GL_SRC_COLOR:
154       func = R200_BLEND_GL_SRC_COLOR;
155       break;
156    case GL_ONE_MINUS_SRC_COLOR:
157       func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
158       break;
159    case GL_SRC_ALPHA:
160       func = R200_BLEND_GL_SRC_ALPHA;
161       break;
162    case GL_ONE_MINUS_SRC_ALPHA:
163       func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
164       break;
165    case GL_DST_ALPHA:
166       func = R200_BLEND_GL_DST_ALPHA;
167       break;
168    case GL_ONE_MINUS_DST_ALPHA:
169       func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
170       break;
171    case GL_SRC_ALPHA_SATURATE:
172       func = (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE : R200_BLEND_GL_ZERO;
173       break;
174    case GL_CONSTANT_COLOR:
175       func = R200_BLEND_GL_CONST_COLOR;
176       break;
177    case GL_ONE_MINUS_CONSTANT_COLOR:
178       func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
179       break;
180    case GL_CONSTANT_ALPHA:
181       func = R200_BLEND_GL_CONST_ALPHA;
182       break;
183    case GL_ONE_MINUS_CONSTANT_ALPHA:
184       func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
185       break;
186    default:
187       func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
188    }
189    return func;
190 }
191
192 /**
193  * Sets both the blend equation and the blend function.
194  * This is done in a single
195  * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
196  * change the interpretation of the blend function.
197  * Also, make sure that blend function and blend equation are set to their default
198  * value if color blending is not enabled, since at least blend equations GL_MIN
199  * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
200  * unknown reasons.
201  */
202 static void r200_set_blend_state( struct gl_context * ctx )
203 {
204    r200ContextPtr rmesa = R200_CONTEXT(ctx);
205    GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
206       ~(R200_ROP_ENABLE | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_ENABLE);
207
208    int func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
209       (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
210    int eqn = R200_COMB_FCN_ADD_CLAMP;
211    int funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
212       (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
213    int eqnA = R200_COMB_FCN_ADD_CLAMP;
214
215    R200_STATECHANGE( rmesa, ctx );
216
217    if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
218       if (ctx->Color.ColorLogicOpEnabled) {
219          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ROP_ENABLE;
220          rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
221          rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
222          return;
223       } else if (ctx->Color.BlendEnabled) {
224          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_ENABLE;
225       }
226       else {
227          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
228          rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
229          rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
230          return;
231       }
232    }
233    else {
234       if (ctx->Color.ColorLogicOpEnabled) {
235          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ROP_ENABLE;
236          rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
237          return;
238       } else if (ctx->Color.BlendEnabled) {
239          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ALPHA_BLEND_ENABLE;
240       }
241       else {
242          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
243          rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
244          return;
245       }
246    }
247
248    func = (blend_factor( ctx->Color.Blend[0].SrcRGB, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
249       (blend_factor( ctx->Color.Blend[0].DstRGB, GL_FALSE ) << R200_DST_BLEND_SHIFT);
250
251    switch(ctx->Color.Blend[0].EquationRGB) {
252    case GL_FUNC_ADD:
253       eqn = R200_COMB_FCN_ADD_CLAMP;
254       break;
255
256    case GL_FUNC_SUBTRACT:
257       eqn = R200_COMB_FCN_SUB_CLAMP;
258       break;
259
260    case GL_FUNC_REVERSE_SUBTRACT:
261       eqn = R200_COMB_FCN_RSUB_CLAMP;
262       break;
263
264    case GL_MIN:
265       eqn = R200_COMB_FCN_MIN;
266       func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
267          (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
268       break;
269
270    case GL_MAX:
271       eqn = R200_COMB_FCN_MAX;
272       func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
273          (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
274       break;
275
276    default:
277       fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
278          __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationRGB );
279       return;
280    }
281
282    if (!rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
283       rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
284       return;
285    }
286
287    funcA = (blend_factor( ctx->Color.Blend[0].SrcA, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
288       (blend_factor( ctx->Color.Blend[0].DstA, GL_FALSE ) << R200_DST_BLEND_SHIFT);
289
290    switch(ctx->Color.Blend[0].EquationA) {
291    case GL_FUNC_ADD:
292       eqnA = R200_COMB_FCN_ADD_CLAMP;
293       break;
294
295    case GL_FUNC_SUBTRACT:
296       eqnA = R200_COMB_FCN_SUB_CLAMP;
297       break;
298
299    case GL_FUNC_REVERSE_SUBTRACT:
300       eqnA = R200_COMB_FCN_RSUB_CLAMP;
301       break;
302
303    case GL_MIN:
304       eqnA = R200_COMB_FCN_MIN;
305       funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
306          (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
307       break;
308
309    case GL_MAX:
310       eqnA = R200_COMB_FCN_MAX;
311       funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
312          (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
313       break;
314
315    default:
316       fprintf( stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
317          __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationA );
318       return;
319    }
320
321    rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqnA | funcA;
322    rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
323
324 }
325
326 static void r200BlendEquationSeparate( struct gl_context *ctx,
327                                        GLenum modeRGB, GLenum modeA )
328 {
329       r200_set_blend_state( ctx );
330 }
331
332 static void r200BlendFuncSeparate( struct gl_context *ctx,
333                                      GLenum sfactorRGB, GLenum dfactorRGB,
334                                      GLenum sfactorA, GLenum dfactorA )
335 {
336       r200_set_blend_state( ctx );
337 }
338
339
340 /* =============================================================
341  * Depth testing
342  */
343
344 static void r200DepthFunc( struct gl_context *ctx, GLenum func )
345 {
346    r200ContextPtr rmesa = R200_CONTEXT(ctx);
347
348    R200_STATECHANGE( rmesa, ctx );
349    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_TEST_MASK;
350
351    switch ( ctx->Depth.Func ) {
352    case GL_NEVER:
353       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEVER;
354       break;
355    case GL_LESS:
356       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LESS;
357       break;
358    case GL_EQUAL:
359       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_EQUAL;
360       break;
361    case GL_LEQUAL:
362       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LEQUAL;
363       break;
364    case GL_GREATER:
365       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GREATER;
366       break;
367    case GL_NOTEQUAL:
368       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEQUAL;
369       break;
370    case GL_GEQUAL:
371       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GEQUAL;
372       break;
373    case GL_ALWAYS:
374       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_ALWAYS;
375       break;
376    }
377 }
378
379 static void r200ClearDepth( struct gl_context *ctx, GLclampd d )
380 {
381    r200ContextPtr rmesa = R200_CONTEXT(ctx);
382    GLuint format = (rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &
383                     R200_DEPTH_FORMAT_MASK);
384
385    switch ( format ) {
386    case R200_DEPTH_FORMAT_16BIT_INT_Z:
387       rmesa->radeon.state.depth.clear = d * 0x0000ffff;
388       break;
389    case R200_DEPTH_FORMAT_24BIT_INT_Z:
390       rmesa->radeon.state.depth.clear = d * 0x00ffffff;
391       break;
392    }
393 }
394
395 static void r200DepthMask( struct gl_context *ctx, GLboolean flag )
396 {
397    r200ContextPtr rmesa = R200_CONTEXT(ctx);
398    R200_STATECHANGE( rmesa, ctx );
399
400    if ( ctx->Depth.Mask ) {
401       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |=  R200_Z_WRITE_ENABLE;
402    } else {
403       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_WRITE_ENABLE;
404    }
405 }
406
407
408 /* =============================================================
409  * Fog
410  */
411
412
413 static void r200Fogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
414 {
415    r200ContextPtr rmesa = R200_CONTEXT(ctx);
416    union { int i; float f; } c, d;
417    GLchan col[4];
418    GLuint i;
419
420    c.i = rmesa->hw.fog.cmd[FOG_C];
421    d.i = rmesa->hw.fog.cmd[FOG_D];
422
423    switch (pname) {
424    case GL_FOG_MODE:
425       if (!ctx->Fog.Enabled)
426          return;
427       R200_STATECHANGE(rmesa, tcl);
428       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK;
429       switch (ctx->Fog.Mode) {
430       case GL_LINEAR:
431          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_LINEAR;
432          if (ctx->Fog.Start == ctx->Fog.End) {
433             c.f = 1.0F;
434             d.f = 1.0F;
435          }
436          else {
437             c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
438             d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
439          }
440          break;
441       case GL_EXP:
442          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP;
443          c.f = 0.0;
444          d.f = -ctx->Fog.Density;
445          break;
446       case GL_EXP2:
447          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP2;
448          c.f = 0.0;
449          d.f = -(ctx->Fog.Density * ctx->Fog.Density);
450          break;
451       default:
452          return;
453       }
454       break;
455    case GL_FOG_DENSITY:
456       switch (ctx->Fog.Mode) {
457       case GL_EXP:
458          c.f = 0.0;
459          d.f = -ctx->Fog.Density;
460          break;
461       case GL_EXP2:
462          c.f = 0.0;
463          d.f = -(ctx->Fog.Density * ctx->Fog.Density);
464          break;
465       default:
466          break;
467       }
468       break;
469    case GL_FOG_START:
470    case GL_FOG_END:
471       if (ctx->Fog.Mode == GL_LINEAR) {
472          if (ctx->Fog.Start == ctx->Fog.End) {
473             c.f = 1.0F;
474             d.f = 1.0F;
475          } else {
476             c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
477             d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
478          }
479       }
480       break;
481    case GL_FOG_COLOR:
482       R200_STATECHANGE( rmesa, ctx );
483       UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
484       i = radeonPackColor( 4, col[0], col[1], col[2], 0 );
485       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_COLOR_MASK;
486       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= i;
487       break;
488    case GL_FOG_COORD_SRC: {
489       GLuint out_0 = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0];
490       GLuint fog   = rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR];
491
492       fog &= ~R200_FOG_USE_MASK;
493       if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD || ctx->VertexProgram.Enabled) {
494          fog   |= R200_FOG_USE_VTX_FOG;
495          out_0 |= R200_VTX_DISCRETE_FOG;
496       }
497       else {
498          fog   |=  R200_FOG_USE_SPEC_ALPHA;
499          out_0 &= ~R200_VTX_DISCRETE_FOG;
500       }
501
502       if ( fog != rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] ) {
503          R200_STATECHANGE( rmesa, ctx );
504          rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = fog;
505       }
506
507       if (out_0 != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0]) {
508          R200_STATECHANGE( rmesa, vtx );
509          rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] = out_0;
510       }
511
512       break;
513    }
514    default:
515       return;
516    }
517
518    if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
519       R200_STATECHANGE( rmesa, fog );
520       rmesa->hw.fog.cmd[FOG_C] = c.i;
521       rmesa->hw.fog.cmd[FOG_D] = d.i;
522    }
523 }
524
525 /* =============================================================
526  * Culling
527  */
528
529 static void r200CullFace( struct gl_context *ctx, GLenum unused )
530 {
531    r200ContextPtr rmesa = R200_CONTEXT(ctx);
532    GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
533    GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
534
535    s |= R200_FFACE_SOLID | R200_BFACE_SOLID;
536    t &= ~(R200_CULL_FRONT | R200_CULL_BACK);
537
538    if ( ctx->Polygon.CullFlag ) {
539       switch ( ctx->Polygon.CullFaceMode ) {
540       case GL_FRONT:
541          s &= ~R200_FFACE_SOLID;
542          t |= R200_CULL_FRONT;
543          break;
544       case GL_BACK:
545          s &= ~R200_BFACE_SOLID;
546          t |= R200_CULL_BACK;
547          break;
548       case GL_FRONT_AND_BACK:
549          s &= ~(R200_FFACE_SOLID | R200_BFACE_SOLID);
550          t |= (R200_CULL_FRONT | R200_CULL_BACK);
551          break;
552       }
553    }
554
555    if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
556       R200_STATECHANGE(rmesa, set );
557       rmesa->hw.set.cmd[SET_SE_CNTL] = s;
558    }
559
560    if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
561       R200_STATECHANGE(rmesa, tcl );
562       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
563    }
564 }
565
566 static void r200FrontFace( struct gl_context *ctx, GLenum mode )
567 {
568    r200ContextPtr rmesa = R200_CONTEXT(ctx);
569
570    R200_STATECHANGE( rmesa, set );
571    rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_FFACE_CULL_DIR_MASK;
572
573    R200_STATECHANGE( rmesa, tcl );
574    rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_CULL_FRONT_IS_CCW;
575
576    /* Winding is inverted when rendering to FBO */
577    if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
578       mode = (mode == GL_CW) ? GL_CCW : GL_CW;
579
580    switch ( mode ) {
581    case GL_CW:
582       rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CW;
583       break;
584    case GL_CCW:
585       rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CCW;
586       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_CULL_FRONT_IS_CCW;
587       break;
588    }
589 }
590
591 /* =============================================================
592  * Point state
593  */
594 static void r200PointSize( struct gl_context *ctx, GLfloat size )
595 {
596    r200ContextPtr rmesa = R200_CONTEXT(ctx);
597    GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
598
599    radeon_print(RADEON_STATE, RADEON_TRACE,
600        "%s(%p) size: %f, fixed point result: %d.%d (%d/16)\n",
601        __func__, ctx, size,
602        ((GLuint)(ctx->Point.Size * 16.0))/16,
603        (((GLuint)(ctx->Point.Size * 16.0))&15)*100/16,
604        ((GLuint)(ctx->Point.Size * 16.0))&15);
605
606    R200_STATECHANGE( rmesa, cst );
607    R200_STATECHANGE( rmesa, ptp );
608    rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff;
609    rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= ((GLuint)(ctx->Point.Size * 16.0));
610 /* this is the size param of the point size calculation (point size reg value
611    is not used when calculation is active). */
612    fcmd[PTP_VPORT_SCALE_PTSIZE] = ctx->Point.Size;
613 }
614
615 static void r200PointParameter( struct gl_context *ctx, GLenum pname, const GLfloat *params)
616 {
617    r200ContextPtr rmesa = R200_CONTEXT(ctx);
618    GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
619
620    switch (pname) {
621    case GL_POINT_SIZE_MIN:
622    /* Can clamp both in tcl and setup - just set both (as does fglrx) */
623       R200_STATECHANGE( rmesa, lin );
624       R200_STATECHANGE( rmesa, ptp );
625       rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= 0xffff;
626       rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Point.MinSize * 16.0) << 16;
627       fcmd[PTP_CLAMP_MIN] = ctx->Point.MinSize;
628       break;
629    case GL_POINT_SIZE_MAX:
630       R200_STATECHANGE( rmesa, cst );
631       R200_STATECHANGE( rmesa, ptp );
632       rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= 0xffff;
633       rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= (GLuint)(ctx->Point.MaxSize * 16.0) << 16;
634       fcmd[PTP_CLAMP_MAX] = ctx->Point.MaxSize;
635       break;
636    case GL_POINT_DISTANCE_ATTENUATION:
637       R200_STATECHANGE( rmesa, vtx );
638       R200_STATECHANGE( rmesa, spr );
639       R200_STATECHANGE( rmesa, ptp );
640       GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
641       rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &=
642          ~(R200_PS_MULT_MASK | R200_PS_LIN_ATT_ZERO | R200_PS_SE_SEL_STATE);
643       /* can't rely on ctx->Point._Attenuated here and test for NEW_POINT in
644          r200ValidateState looks like overkill */
645       if (ctx->Point.Params[0] != 1.0 ||
646           ctx->Point.Params[1] != 0.0 ||
647           ctx->Point.Params[2] != 0.0 ||
648           (ctx->VertexProgram.Enabled && ctx->VertexProgram.PointSizeEnabled)) {
649          /* all we care for vp would be the ps_se_sel_state setting */
650          fcmd[PTP_ATT_CONST_QUAD] = ctx->Point.Params[2];
651          fcmd[PTP_ATT_CONST_LIN] = ctx->Point.Params[1];
652          fcmd[PTP_ATT_CONST_CON] = ctx->Point.Params[0];
653          rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_MULT_ATTENCONST;
654          if (ctx->Point.Params[1] == 0.0)
655             rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_LIN_ATT_ZERO;
656 /* FIXME: setting this here doesn't look quite ok - we only want to do
657           that if we're actually drawing points probably */
658          rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_PT_SIZE;
659          rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= R200_VTX_POINT_SIZE;
660       }
661       else {
662          rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
663             R200_PS_SE_SEL_STATE | R200_PS_MULT_CONST;
664          rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_PT_SIZE;
665          rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~R200_VTX_POINT_SIZE;
666       }
667       break;
668    case GL_POINT_FADE_THRESHOLD_SIZE:
669       /* don't support multisampling, so doesn't matter. */
670       break;
671    /* can't do these but don't need them.
672    case GL_POINT_SPRITE_R_MODE_NV:
673    case GL_POINT_SPRITE_COORD_ORIGIN: */
674    default:
675       fprintf(stderr, "bad pname parameter in r200PointParameter\n");
676       return;
677    }
678 }
679
680 /* =============================================================
681  * Line state
682  */
683 static void r200LineWidth( struct gl_context *ctx, GLfloat widthf )
684 {
685    r200ContextPtr rmesa = R200_CONTEXT(ctx);
686
687    R200_STATECHANGE( rmesa, lin );
688    R200_STATECHANGE( rmesa, set );
689
690    /* Line width is stored in U6.4 format.
691     * Same min/max limits for AA, non-AA lines.
692     */
693    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff;
694    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)
695       (CLAMP(widthf, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth) * 16.0);
696
697    if ( widthf > 1.0 ) {
698       rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_WIDELINE_ENABLE;
699    } else {
700       rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_WIDELINE_ENABLE;
701    }
702 }
703
704 static void r200LineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
705 {
706    r200ContextPtr rmesa = R200_CONTEXT(ctx);
707
708    R200_STATECHANGE( rmesa, lin );
709    rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
710       ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
711 }
712
713
714 /* =============================================================
715  * Masks
716  */
717 static void r200ColorMask( struct gl_context *ctx,
718                            GLboolean r, GLboolean g,
719                            GLboolean b, GLboolean a )
720 {
721    r200ContextPtr rmesa = R200_CONTEXT(ctx);
722    GLuint mask;
723    struct radeon_renderbuffer *rrb;
724    GLuint flag = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & ~R200_PLANE_MASK_ENABLE;
725
726    rrb = radeon_get_colorbuffer(&rmesa->radeon);
727    if (!rrb)
728      return;
729    mask = radeonPackColor( rrb->cpp,
730                            ctx->Color.ColorMask[0][RCOMP],
731                            ctx->Color.ColorMask[0][GCOMP],
732                            ctx->Color.ColorMask[0][BCOMP],
733                            ctx->Color.ColorMask[0][ACOMP] );
734
735
736    if (!(r && g && b && a))
737       flag |= R200_PLANE_MASK_ENABLE;
738
739    if ( rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] != flag ) {
740       R200_STATECHANGE( rmesa, ctx );
741       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = flag;
742    }
743
744    if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
745       R200_STATECHANGE( rmesa, msk );
746       rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
747    }
748 }
749
750
751 /* =============================================================
752  * Polygon state
753  */
754
755 static void r200PolygonOffset( struct gl_context *ctx,
756                                GLfloat factor, GLfloat units )
757 {
758    r200ContextPtr rmesa = R200_CONTEXT(ctx);
759    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
760    float_ui32_type constant =  { units * depthScale };
761    float_ui32_type factoru = { factor };
762
763 /*    factor *= 2; */
764 /*    constant *= 2; */
765
766 /*    fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
767
768    R200_STATECHANGE( rmesa, zbs );
769    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR]   = factoru.ui32;
770    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
771 }
772
773 static void r200PolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
774 {
775    r200ContextPtr rmesa = R200_CONTEXT(ctx);
776    GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
777
778    /* Can't generally do unfilled via tcl, but some good special
779     * cases work.
780     */
781    TCL_FALLBACK( ctx, R200_TCL_FALLBACK_UNFILLED, flag);
782    if (rmesa->radeon.TclFallback) {
783       r200ChooseRenderState( ctx );
784       r200ChooseVertexState( ctx );
785    }
786 }
787
788
789 /* =============================================================
790  * Rendering attributes
791  *
792  * We really don't want to recalculate all this every time we bind a
793  * texture.  These things shouldn't change all that often, so it makes
794  * sense to break them out of the core texture state update routines.
795  */
796
797 /* Examine lighting and texture state to determine if separate specular
798  * should be enabled.
799  */
800 static void r200UpdateSpecular( struct gl_context *ctx )
801 {
802    r200ContextPtr rmesa = R200_CONTEXT(ctx);
803    uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
804
805    R200_STATECHANGE( rmesa, tcl );
806    R200_STATECHANGE( rmesa, vtx );
807
808    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_0_SHIFT);
809    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_1_SHIFT);
810    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_0;
811    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_1;
812    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHTING_ENABLE;
813
814    p &= ~R200_SPECULAR_ENABLE;
815
816    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_DIFFUSE_SPECULAR_COMBINE;
817
818
819    if (ctx->Light.Enabled &&
820        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
821       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
822          ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
823           (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
824       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
825       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
826       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
827       p |=  R200_SPECULAR_ENABLE;
828       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &=
829          ~R200_DIFFUSE_SPECULAR_COMBINE;
830    }
831    else if (ctx->Light.Enabled) {
832       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
833          ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
834       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
835       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
836    } else if (ctx->Fog.ColorSumEnabled ) {
837       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
838          ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
839           (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
840       p |=  R200_SPECULAR_ENABLE;
841    } else {
842       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
843          ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
844    }
845
846    if (ctx->Fog.Enabled) {
847       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
848          ((R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
849       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
850    }
851
852    if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
853       R200_STATECHANGE( rmesa, ctx );
854       rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
855    }
856
857    /* Update vertex/render formats
858     */
859    if (rmesa->radeon.TclFallback) {
860       r200ChooseRenderState( ctx );
861       r200ChooseVertexState( ctx );
862    }
863 }
864
865
866 /* =============================================================
867  * Materials
868  */
869
870
871 /* Update on colormaterial, material emmissive/ambient,
872  * lightmodel.globalambient
873  */
874 static void update_global_ambient( struct gl_context *ctx )
875 {
876    r200ContextPtr rmesa = R200_CONTEXT(ctx);
877    float *fcmd = (float *)R200_DB_STATE( glt );
878
879    /* Need to do more if both emmissive & ambient are PREMULT:
880     * I believe this is not nessary when using source_material. This condition thus
881     * will never happen currently, and the function has no dependencies on materials now
882     */
883    if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] &
884        ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
885         (3 << R200_FRONT_AMBIENT_SOURCE_SHIFT))) == 0)
886    {
887       COPY_3V( &fcmd[GLT_RED],
888                ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
889       ACC_SCALE_3V( &fcmd[GLT_RED],
890                    ctx->Light.Model.Ambient,
891                    ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
892    }
893    else
894    {
895       COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
896    }
897
898    R200_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
899 }
900
901 /* Update on change to
902  *    - light[p].colors
903  *    - light[p].enabled
904  */
905 static void update_light_colors( struct gl_context *ctx, GLuint p )
906 {
907    struct gl_light *l = &ctx->Light.Light[p];
908
909 /*     fprintf(stderr, "%s\n", __FUNCTION__); */
910
911    if (l->Enabled) {
912       r200ContextPtr rmesa = R200_CONTEXT(ctx);
913       float *fcmd = (float *)R200_DB_STATE( lit[p] );
914
915       COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
916       COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
917       COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
918
919       R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
920    }
921 }
922
923 static void r200ColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
924 {
925       r200ContextPtr rmesa = R200_CONTEXT(ctx);
926       GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1];
927       light_model_ctl1 &= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
928                            (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
929                            (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
930                    (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
931                    (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
932                    (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT) |
933                    (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
934                    (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT));
935
936    if (ctx->Light.ColorMaterialEnabled) {
937       GLuint mask = ctx->Light.ColorMaterialBitmask;
938
939       if (mask & MAT_BIT_FRONT_EMISSION) {
940          light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
941                              R200_FRONT_EMISSIVE_SOURCE_SHIFT);
942       }
943       else
944          light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
945                              R200_FRONT_EMISSIVE_SOURCE_SHIFT);
946
947       if (mask & MAT_BIT_FRONT_AMBIENT) {
948          light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
949                              R200_FRONT_AMBIENT_SOURCE_SHIFT);
950       }
951       else
952          light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
953                              R200_FRONT_AMBIENT_SOURCE_SHIFT);
954
955       if (mask & MAT_BIT_FRONT_DIFFUSE) {
956          light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
957                              R200_FRONT_DIFFUSE_SOURCE_SHIFT);
958       }
959       else
960          light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
961                              R200_FRONT_DIFFUSE_SOURCE_SHIFT);
962
963       if (mask & MAT_BIT_FRONT_SPECULAR) {
964          light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
965                              R200_FRONT_SPECULAR_SOURCE_SHIFT);
966       }
967       else {
968          light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
969                              R200_FRONT_SPECULAR_SOURCE_SHIFT);
970       }
971
972       if (mask & MAT_BIT_BACK_EMISSION) {
973          light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
974                              R200_BACK_EMISSIVE_SOURCE_SHIFT);
975       }
976
977       else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
978                              R200_BACK_EMISSIVE_SOURCE_SHIFT);
979
980       if (mask & MAT_BIT_BACK_AMBIENT) {
981          light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
982                              R200_BACK_AMBIENT_SOURCE_SHIFT);
983       }
984       else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
985                              R200_BACK_AMBIENT_SOURCE_SHIFT);
986
987       if (mask & MAT_BIT_BACK_DIFFUSE) {
988          light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
989                              R200_BACK_DIFFUSE_SOURCE_SHIFT);
990    }
991       else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
992                              R200_BACK_DIFFUSE_SOURCE_SHIFT);
993
994       if (mask & MAT_BIT_BACK_SPECULAR) {
995          light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
996                              R200_BACK_SPECULAR_SOURCE_SHIFT);
997       }
998       else {
999          light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
1000                              R200_BACK_SPECULAR_SOURCE_SHIFT);
1001       }
1002       }
1003    else {
1004        /* Default to SOURCE_MATERIAL:
1005         */
1006      light_model_ctl1 |=
1007         (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
1008         (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
1009         (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
1010         (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
1011         (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
1012         (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT) |
1013         (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
1014         (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT);
1015    }
1016
1017    if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) {
1018       R200_STATECHANGE( rmesa, tcl );
1019       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1;
1020    }
1021
1022
1023 }
1024
1025 void r200UpdateMaterial( struct gl_context *ctx )
1026 {
1027    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1028    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
1029    GLfloat *fcmd = (GLfloat *)R200_DB_STATE( mtl[0] );
1030    GLfloat *fcmd2 = (GLfloat *)R200_DB_STATE( mtl[1] );
1031    GLuint mask = ~0;
1032
1033    /* Might be possible and faster to update everything unconditionally? */
1034    if (ctx->Light.ColorMaterialEnabled)
1035       mask &= ~ctx->Light.ColorMaterialBitmask;
1036
1037    if (R200_DEBUG & RADEON_STATE)
1038       fprintf(stderr, "%s\n", __FUNCTION__);
1039
1040    if (mask & MAT_BIT_FRONT_EMISSION) {
1041       fcmd[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_FRONT_EMISSION][0];
1042       fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
1043       fcmd[MTL_EMMISSIVE_BLUE]  = mat[MAT_ATTRIB_FRONT_EMISSION][2];
1044       fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
1045    }
1046    if (mask & MAT_BIT_FRONT_AMBIENT) {
1047       fcmd[MTL_AMBIENT_RED]     = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
1048       fcmd[MTL_AMBIENT_GREEN]   = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
1049       fcmd[MTL_AMBIENT_BLUE]    = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
1050       fcmd[MTL_AMBIENT_ALPHA]   = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
1051    }
1052    if (mask & MAT_BIT_FRONT_DIFFUSE) {
1053       fcmd[MTL_DIFFUSE_RED]     = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
1054       fcmd[MTL_DIFFUSE_GREEN]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
1055       fcmd[MTL_DIFFUSE_BLUE]    = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
1056       fcmd[MTL_DIFFUSE_ALPHA]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
1057    }
1058    if (mask & MAT_BIT_FRONT_SPECULAR) {
1059       fcmd[MTL_SPECULAR_RED]    = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
1060       fcmd[MTL_SPECULAR_GREEN]  = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
1061       fcmd[MTL_SPECULAR_BLUE]   = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
1062       fcmd[MTL_SPECULAR_ALPHA]  = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
1063    }
1064    if (mask & MAT_BIT_FRONT_SHININESS) {
1065       fcmd[MTL_SHININESS]       = mat[MAT_ATTRIB_FRONT_SHININESS][0];
1066    }
1067
1068    if (mask & MAT_BIT_BACK_EMISSION) {
1069       fcmd2[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_BACK_EMISSION][0];
1070       fcmd2[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_BACK_EMISSION][1];
1071       fcmd2[MTL_EMMISSIVE_BLUE]  = mat[MAT_ATTRIB_BACK_EMISSION][2];
1072       fcmd2[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_BACK_EMISSION][3];
1073    }
1074    if (mask & MAT_BIT_BACK_AMBIENT) {
1075       fcmd2[MTL_AMBIENT_RED]     = mat[MAT_ATTRIB_BACK_AMBIENT][0];
1076       fcmd2[MTL_AMBIENT_GREEN]   = mat[MAT_ATTRIB_BACK_AMBIENT][1];
1077       fcmd2[MTL_AMBIENT_BLUE]    = mat[MAT_ATTRIB_BACK_AMBIENT][2];
1078       fcmd2[MTL_AMBIENT_ALPHA]   = mat[MAT_ATTRIB_BACK_AMBIENT][3];
1079    }
1080    if (mask & MAT_BIT_BACK_DIFFUSE) {
1081       fcmd2[MTL_DIFFUSE_RED]     = mat[MAT_ATTRIB_BACK_DIFFUSE][0];
1082       fcmd2[MTL_DIFFUSE_GREEN]   = mat[MAT_ATTRIB_BACK_DIFFUSE][1];
1083       fcmd2[MTL_DIFFUSE_BLUE]    = mat[MAT_ATTRIB_BACK_DIFFUSE][2];
1084       fcmd2[MTL_DIFFUSE_ALPHA]   = mat[MAT_ATTRIB_BACK_DIFFUSE][3];
1085    }
1086    if (mask & MAT_BIT_BACK_SPECULAR) {
1087       fcmd2[MTL_SPECULAR_RED]    = mat[MAT_ATTRIB_BACK_SPECULAR][0];
1088       fcmd2[MTL_SPECULAR_GREEN]  = mat[MAT_ATTRIB_BACK_SPECULAR][1];
1089       fcmd2[MTL_SPECULAR_BLUE]   = mat[MAT_ATTRIB_BACK_SPECULAR][2];
1090       fcmd2[MTL_SPECULAR_ALPHA]  = mat[MAT_ATTRIB_BACK_SPECULAR][3];
1091    }
1092    if (mask & MAT_BIT_BACK_SHININESS) {
1093       fcmd2[MTL_SHININESS]       = mat[MAT_ATTRIB_BACK_SHININESS][0];
1094    }
1095
1096    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] );
1097    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[1] );
1098
1099    /* currently material changes cannot trigger a global ambient change, I believe this is correct
1100     update_global_ambient( ctx ); */
1101 }
1102
1103 /* _NEW_LIGHT
1104  * _NEW_MODELVIEW
1105  * _MESA_NEW_NEED_EYE_COORDS
1106  *
1107  * Uses derived state from mesa:
1108  *       _VP_inf_norm
1109  *       _h_inf_norm
1110  *       _Position
1111  *       _NormSpotDirection
1112  *       _ModelViewInvScale
1113  *       _NeedEyeCoords
1114  *       _EyeZDir
1115  *
1116  * which are calculated in light.c and are correct for the current
1117  * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
1118  * and _MESA_NEW_NEED_EYE_COORDS.
1119  */
1120 static void update_light( struct gl_context *ctx )
1121 {
1122    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1123
1124    /* Have to check these, or have an automatic shortcircuit mechanism
1125     * to remove noop statechanges. (Or just do a better job on the
1126     * front end).
1127     */
1128    {
1129       GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0];
1130
1131       if (ctx->_NeedEyeCoords)
1132          tmp &= ~R200_LIGHT_IN_MODELSPACE;
1133       else
1134          tmp |= R200_LIGHT_IN_MODELSPACE;
1135
1136       if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0])
1137       {
1138          R200_STATECHANGE( rmesa, tcl );
1139          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] = tmp;
1140       }
1141    }
1142
1143    {
1144       GLfloat *fcmd = (GLfloat *)R200_DB_STATE( eye );
1145       fcmd[EYE_X] = ctx->_EyeZDir[0];
1146       fcmd[EYE_Y] = ctx->_EyeZDir[1];
1147       fcmd[EYE_Z] = - ctx->_EyeZDir[2];
1148       fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
1149       R200_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
1150    }
1151
1152
1153
1154    if (ctx->Light.Enabled) {
1155       GLint p;
1156       for (p = 0 ; p < MAX_LIGHTS; p++) {
1157          if (ctx->Light.Light[p].Enabled) {
1158             struct gl_light *l = &ctx->Light.Light[p];
1159             GLfloat *fcmd = (GLfloat *)R200_DB_STATE( lit[p] );
1160
1161             if (l->EyePosition[3] == 0.0) {
1162                COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
1163                COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
1164                fcmd[LIT_POSITION_W] = 0;
1165                fcmd[LIT_DIRECTION_W] = 0;
1166             } else {
1167                COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
1168                fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
1169                fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
1170                fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
1171                fcmd[LIT_DIRECTION_W] = 0;
1172             }
1173
1174             R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
1175          }
1176       }
1177    }
1178 }
1179
1180 static void r200Lightfv( struct gl_context *ctx, GLenum light,
1181                            GLenum pname, const GLfloat *params )
1182 {
1183    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1184    GLint p = light - GL_LIGHT0;
1185    struct gl_light *l = &ctx->Light.Light[p];
1186    GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
1187
1188
1189    switch (pname) {
1190    case GL_AMBIENT:
1191    case GL_DIFFUSE:
1192    case GL_SPECULAR:
1193       update_light_colors( ctx, p );
1194       break;
1195
1196    case GL_SPOT_DIRECTION:
1197       /* picked up in update_light */
1198       break;
1199
1200    case GL_POSITION: {
1201       /* positions picked up in update_light, but can do flag here */
1202       GLuint flag = (p&1)? R200_LIGHT_1_IS_LOCAL : R200_LIGHT_0_IS_LOCAL;
1203       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1204
1205       R200_STATECHANGE(rmesa, tcl);
1206       if (l->EyePosition[3] != 0.0F)
1207          rmesa->hw.tcl.cmd[idx] |= flag;
1208       else
1209          rmesa->hw.tcl.cmd[idx] &= ~flag;
1210       break;
1211    }
1212
1213    case GL_SPOT_EXPONENT:
1214       R200_STATECHANGE(rmesa, lit[p]);
1215       fcmd[LIT_SPOT_EXPONENT] = params[0];
1216       break;
1217
1218    case GL_SPOT_CUTOFF: {
1219       GLuint flag = (p&1) ? R200_LIGHT_1_IS_SPOT : R200_LIGHT_0_IS_SPOT;
1220       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1221
1222       R200_STATECHANGE(rmesa, lit[p]);
1223       fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
1224
1225       R200_STATECHANGE(rmesa, tcl);
1226       if (l->SpotCutoff != 180.0F)
1227          rmesa->hw.tcl.cmd[idx] |= flag;
1228       else
1229          rmesa->hw.tcl.cmd[idx] &= ~flag;
1230
1231       break;
1232    }
1233
1234    case GL_CONSTANT_ATTENUATION:
1235       R200_STATECHANGE(rmesa, lit[p]);
1236       fcmd[LIT_ATTEN_CONST] = params[0];
1237       if ( params[0] == 0.0 )
1238          fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
1239       else
1240          fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
1241       break;
1242    case GL_LINEAR_ATTENUATION:
1243       R200_STATECHANGE(rmesa, lit[p]);
1244       fcmd[LIT_ATTEN_LINEAR] = params[0];
1245       break;
1246    case GL_QUADRATIC_ATTENUATION:
1247       R200_STATECHANGE(rmesa, lit[p]);
1248       fcmd[LIT_ATTEN_QUADRATIC] = params[0];
1249       break;
1250    default:
1251       return;
1252    }
1253
1254    /* Set RANGE_ATTEN only when needed */
1255    switch (pname) {
1256    case GL_POSITION:
1257    case GL_CONSTANT_ATTENUATION:
1258    case GL_LINEAR_ATTENUATION:
1259    case GL_QUADRATIC_ATTENUATION: {
1260       GLuint *icmd = (GLuint *)R200_DB_STATE( tcl );
1261       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1262       GLuint atten_flag = ( p&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN
1263                                   : R200_LIGHT_0_ENABLE_RANGE_ATTEN;
1264       GLuint atten_const_flag = ( p&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN
1265                                   : R200_LIGHT_0_CONSTANT_RANGE_ATTEN;
1266
1267       if ( l->EyePosition[3] == 0.0F ||
1268            ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1269              fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1270          /* Disable attenuation */
1271          icmd[idx] &= ~atten_flag;
1272       } else {
1273          if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1274             /* Enable only constant portion of attenuation calculation */
1275             icmd[idx] |= ( atten_flag | atten_const_flag );
1276          } else {
1277             /* Enable full attenuation calculation */
1278             icmd[idx] &= ~atten_const_flag;
1279             icmd[idx] |= atten_flag;
1280          }
1281       }
1282
1283       R200_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1284       break;
1285    }
1286    default:
1287      break;
1288    }
1289 }
1290
1291 static void r200UpdateLocalViewer ( struct gl_context *ctx )
1292 {
1293 /* It looks like for the texgen modes GL_SPHERE_MAP, GL_NORMAL_MAP and
1294    GL_REFLECTION_MAP we need R200_LOCAL_VIEWER set (fglrx does exactly that
1295    for these and only these modes). This means specular highlights may turn out
1296    wrong in some cases when lighting is enabled but GL_LIGHT_MODEL_LOCAL_VIEWER
1297    is not set, though it seems to happen rarely and the effect seems quite
1298    subtle. May need TCL fallback to fix it completely, though I'm not sure
1299    how you'd identify the cases where the specular highlights indeed will
1300    be wrong. Don't know if fglrx does something special in that case.
1301 */
1302    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1303    R200_STATECHANGE( rmesa, tcl );
1304    if (ctx->Light.Model.LocalViewer ||
1305        ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
1306       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LOCAL_VIEWER;
1307    else
1308       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LOCAL_VIEWER;
1309 }
1310
1311 static void r200LightModelfv( struct gl_context *ctx, GLenum pname,
1312                                 const GLfloat *param )
1313 {
1314    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1315
1316    switch (pname) {
1317       case GL_LIGHT_MODEL_AMBIENT:
1318          update_global_ambient( ctx );
1319          break;
1320
1321       case GL_LIGHT_MODEL_LOCAL_VIEWER:
1322          r200UpdateLocalViewer( ctx );
1323          break;
1324
1325       case GL_LIGHT_MODEL_TWO_SIDE:
1326          R200_STATECHANGE( rmesa, tcl );
1327          if (ctx->Light.Model.TwoSide)
1328             rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHT_TWOSIDE;
1329          else
1330             rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~(R200_LIGHT_TWOSIDE);
1331          if (rmesa->radeon.TclFallback) {
1332             r200ChooseRenderState( ctx );
1333             r200ChooseVertexState( ctx );
1334          }
1335          break;
1336
1337       case GL_LIGHT_MODEL_COLOR_CONTROL:
1338          r200UpdateSpecular(ctx);
1339          break;
1340
1341       default:
1342          break;
1343    }
1344 }
1345
1346 static void r200ShadeModel( struct gl_context *ctx, GLenum mode )
1347 {
1348    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1349    GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1350
1351    s &= ~(R200_DIFFUSE_SHADE_MASK |
1352           R200_ALPHA_SHADE_MASK |
1353           R200_SPECULAR_SHADE_MASK |
1354           R200_FOG_SHADE_MASK |
1355           R200_DISC_FOG_SHADE_MASK);
1356
1357    switch ( mode ) {
1358    case GL_FLAT:
1359       s |= (R200_DIFFUSE_SHADE_FLAT |
1360             R200_ALPHA_SHADE_FLAT |
1361             R200_SPECULAR_SHADE_FLAT |
1362             R200_FOG_SHADE_FLAT |
1363             R200_DISC_FOG_SHADE_FLAT);
1364       break;
1365    case GL_SMOOTH:
1366       s |= (R200_DIFFUSE_SHADE_GOURAUD |
1367             R200_ALPHA_SHADE_GOURAUD |
1368             R200_SPECULAR_SHADE_GOURAUD |
1369             R200_FOG_SHADE_GOURAUD |
1370             R200_DISC_FOG_SHADE_GOURAUD);
1371       break;
1372    default:
1373       return;
1374    }
1375
1376    if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1377       R200_STATECHANGE( rmesa, set );
1378       rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1379    }
1380 }
1381
1382
1383 /* =============================================================
1384  * User clip planes
1385  */
1386
1387 static void r200ClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1388 {
1389    GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1390    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1391    GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1392
1393    R200_STATECHANGE( rmesa, ucp[p] );
1394    rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1395    rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1396    rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1397    rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1398 }
1399
1400 static void r200UpdateClipPlanes( struct gl_context *ctx )
1401 {
1402    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1403    GLuint p;
1404
1405    for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1406       if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1407          GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1408
1409          R200_STATECHANGE( rmesa, ucp[p] );
1410          rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1411          rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1412          rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1413          rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1414       }
1415    }
1416 }
1417
1418
1419 /* =============================================================
1420  * Stencil
1421  */
1422
1423 static void
1424 r200StencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1425                          GLint ref, GLuint mask )
1426 {
1427    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1428    GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << R200_STENCIL_REF_SHIFT) |
1429                      ((ctx->Stencil.ValueMask[0] & 0xff) << R200_STENCIL_MASK_SHIFT));
1430
1431    R200_STATECHANGE( rmesa, ctx );
1432    R200_STATECHANGE( rmesa, msk );
1433
1434    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_STENCIL_TEST_MASK;
1435    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(R200_STENCIL_REF_MASK|
1436                                                    R200_STENCIL_VALUE_MASK);
1437
1438    switch ( ctx->Stencil.Function[0] ) {
1439    case GL_NEVER:
1440       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEVER;
1441       break;
1442    case GL_LESS:
1443       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LESS;
1444       break;
1445    case GL_EQUAL:
1446       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_EQUAL;
1447       break;
1448    case GL_LEQUAL:
1449       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LEQUAL;
1450       break;
1451    case GL_GREATER:
1452       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GREATER;
1453       break;
1454    case GL_NOTEQUAL:
1455       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEQUAL;
1456       break;
1457    case GL_GEQUAL:
1458       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GEQUAL;
1459       break;
1460    case GL_ALWAYS:
1461       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_ALWAYS;
1462       break;
1463    }
1464
1465    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1466 }
1467
1468 static void
1469 r200StencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1470 {
1471    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1472
1473    R200_STATECHANGE( rmesa, msk );
1474    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~R200_STENCIL_WRITE_MASK;
1475    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1476       ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT);
1477 }
1478
1479 static void
1480 r200StencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1481                        GLenum zfail, GLenum zpass )
1482 {
1483    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1484
1485    R200_STATECHANGE( rmesa, ctx );
1486    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(R200_STENCIL_FAIL_MASK |
1487                                                R200_STENCIL_ZFAIL_MASK |
1488                                                R200_STENCIL_ZPASS_MASK);
1489
1490    switch ( ctx->Stencil.FailFunc[0] ) {
1491    case GL_KEEP:
1492       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_KEEP;
1493       break;
1494    case GL_ZERO:
1495       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_ZERO;
1496       break;
1497    case GL_REPLACE:
1498       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_REPLACE;
1499       break;
1500    case GL_INCR:
1501       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC;
1502       break;
1503    case GL_DECR:
1504       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC;
1505       break;
1506    case GL_INCR_WRAP_EXT:
1507       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC_WRAP;
1508       break;
1509    case GL_DECR_WRAP_EXT:
1510       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC_WRAP;
1511       break;
1512    case GL_INVERT:
1513       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INVERT;
1514       break;
1515    }
1516
1517    switch ( ctx->Stencil.ZFailFunc[0] ) {
1518    case GL_KEEP:
1519       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_KEEP;
1520       break;
1521    case GL_ZERO:
1522       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_ZERO;
1523       break;
1524    case GL_REPLACE:
1525       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_REPLACE;
1526       break;
1527    case GL_INCR:
1528       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC;
1529       break;
1530    case GL_DECR:
1531       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC;
1532       break;
1533    case GL_INCR_WRAP_EXT:
1534       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC_WRAP;
1535       break;
1536    case GL_DECR_WRAP_EXT:
1537       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC_WRAP;
1538       break;
1539    case GL_INVERT:
1540       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INVERT;
1541       break;
1542    }
1543
1544    switch ( ctx->Stencil.ZPassFunc[0] ) {
1545    case GL_KEEP:
1546       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_KEEP;
1547       break;
1548    case GL_ZERO:
1549       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_ZERO;
1550       break;
1551    case GL_REPLACE:
1552       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_REPLACE;
1553       break;
1554    case GL_INCR:
1555       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC;
1556       break;
1557    case GL_DECR:
1558       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC;
1559       break;
1560    case GL_INCR_WRAP_EXT:
1561       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC_WRAP;
1562       break;
1563    case GL_DECR_WRAP_EXT:
1564       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC_WRAP;
1565       break;
1566    case GL_INVERT:
1567       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INVERT;
1568       break;
1569    }
1570 }
1571
1572 static void r200ClearStencil( struct gl_context *ctx, GLint s )
1573 {
1574    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1575
1576    rmesa->radeon.state.stencil.clear =
1577       ((GLuint) (ctx->Stencil.Clear & 0xff) |
1578        (0xff << R200_STENCIL_MASK_SHIFT) |
1579        ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT));
1580 }
1581
1582
1583 /* =============================================================
1584  * Window position and viewport transformation
1585  */
1586
1587 /**
1588  * Called when window size or position changes or viewport or depth range
1589  * state is changed.  We update the hardware viewport state here.
1590  */
1591 void r200UpdateWindow( struct gl_context *ctx )
1592 {
1593    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1594    __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1595    GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
1596    GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
1597    const GLfloat *v = ctx->Viewport._WindowMap.m;
1598    const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
1599    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1600    GLfloat y_scale, y_bias;
1601
1602    if (render_to_fbo) {
1603       y_scale = 1.0;
1604       y_bias = 0;
1605    } else {
1606       y_scale = -1.0;
1607       y_bias = yoffset;
1608    }
1609
1610    float_ui32_type sx = { v[MAT_SX] };
1611    float_ui32_type tx = { v[MAT_TX] + xoffset };
1612    float_ui32_type sy = { v[MAT_SY] * y_scale };
1613    float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias };
1614    float_ui32_type sz = { v[MAT_SZ] * depthScale };
1615    float_ui32_type tz = { v[MAT_TZ] * depthScale };
1616
1617    R200_STATECHANGE( rmesa, vpt );
1618
1619    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = sx.ui32;
1620    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1621    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE]  = sy.ui32;
1622    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1623    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE]  = sz.ui32;
1624    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1625 }
1626
1627 void r200_vtbl_update_scissor( struct gl_context *ctx )
1628 {
1629    r200ContextPtr r200 = R200_CONTEXT(ctx);
1630    unsigned x1, y1, x2, y2;
1631    struct radeon_renderbuffer *rrb;
1632
1633    R200_SET_STATE(r200, set, SET_RE_CNTL, R200_SCISSOR_ENABLE | r200->hw.set.cmd[SET_RE_CNTL]);
1634
1635    if (r200->radeon.state.scissor.enabled) {
1636       x1 = r200->radeon.state.scissor.rect.x1;
1637       y1 = r200->radeon.state.scissor.rect.y1;
1638       x2 = r200->radeon.state.scissor.rect.x2;
1639       y2 = r200->radeon.state.scissor.rect.y2;
1640    } else {
1641       rrb = radeon_get_colorbuffer(&r200->radeon);
1642       x1 = 0;
1643       y1 = 0;
1644       x2 = rrb->base.Width - 1;
1645       y2 = rrb->base.Height - 1;
1646    }
1647
1648    R200_SET_STATE(r200, sci, SCI_XY_1, x1 | (y1 << 16));
1649    R200_SET_STATE(r200, sci, SCI_XY_2, x2 | (y2 << 16));
1650 }
1651
1652
1653 static void r200Viewport( struct gl_context *ctx, GLint x, GLint y,
1654                             GLsizei width, GLsizei height )
1655 {
1656    /* Don't pipeline viewport changes, conflict with window offset
1657     * setting below.  Could apply deltas to rescue pipelined viewport
1658     * values, or keep the originals hanging around.
1659     */
1660    r200UpdateWindow( ctx );
1661
1662    radeon_viewport(ctx, x, y, width, height);
1663 }
1664
1665 static void r200DepthRange( struct gl_context *ctx, GLclampd nearval,
1666                               GLclampd farval )
1667 {
1668    r200UpdateWindow( ctx );
1669 }
1670
1671 void r200UpdateViewportOffset( struct gl_context *ctx )
1672 {
1673    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1674    __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1675    GLfloat xoffset = (GLfloat)dPriv->x;
1676    GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1677    const GLfloat *v = ctx->Viewport._WindowMap.m;
1678
1679    float_ui32_type tx;
1680    float_ui32_type ty;
1681
1682    tx.f = v[MAT_TX] + xoffset;
1683    ty.f = (- v[MAT_TY]) + yoffset;
1684
1685    if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
1686         rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
1687    {
1688       /* Note: this should also modify whatever data the context reset
1689        * code uses...
1690        */
1691       R200_STATECHANGE( rmesa, vpt );
1692       rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1693       rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1694
1695       /* update polygon stipple x/y screen offset */
1696       {
1697          GLuint stx, sty;
1698          GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1699
1700          m &= ~(R200_STIPPLE_X_OFFSET_MASK |
1701                 R200_STIPPLE_Y_OFFSET_MASK);
1702
1703          /* add magic offsets, then invert */
1704          stx = 31 - ((dPriv->x - 1) & R200_STIPPLE_COORD_MASK);
1705          sty = 31 - ((dPriv->y + dPriv->h - 1)
1706                      & R200_STIPPLE_COORD_MASK);
1707
1708          m |= ((stx << R200_STIPPLE_X_OFFSET_SHIFT) |
1709                (sty << R200_STIPPLE_Y_OFFSET_SHIFT));
1710
1711          if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1712             R200_STATECHANGE( rmesa, msc );
1713             rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1714          }
1715       }
1716    }
1717
1718    radeonUpdateScissor( ctx );
1719 }
1720
1721
1722
1723 /* =============================================================
1724  * Miscellaneous
1725  */
1726
1727 static void r200ClearColor( struct gl_context *ctx, const GLfloat c[4] )
1728 {
1729    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1730    GLubyte color[4];
1731    struct radeon_renderbuffer *rrb;
1732
1733    rrb = radeon_get_colorbuffer(&rmesa->radeon);
1734    if (!rrb)
1735      return;
1736    CLAMPED_FLOAT_TO_UBYTE(color[0], c[0]);
1737    CLAMPED_FLOAT_TO_UBYTE(color[1], c[1]);
1738    CLAMPED_FLOAT_TO_UBYTE(color[2], c[2]);
1739    CLAMPED_FLOAT_TO_UBYTE(color[3], c[3]);
1740    rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
1741                                              color[0], color[1],
1742                                              color[2], color[3] );
1743 }
1744
1745
1746 static void r200RenderMode( struct gl_context *ctx, GLenum mode )
1747 {
1748    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1749    FALLBACK( rmesa, R200_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1750 }
1751
1752
1753 static GLuint r200_rop_tab[] = {
1754    R200_ROP_CLEAR,
1755    R200_ROP_AND,
1756    R200_ROP_AND_REVERSE,
1757    R200_ROP_COPY,
1758    R200_ROP_AND_INVERTED,
1759    R200_ROP_NOOP,
1760    R200_ROP_XOR,
1761    R200_ROP_OR,
1762    R200_ROP_NOR,
1763    R200_ROP_EQUIV,
1764    R200_ROP_INVERT,
1765    R200_ROP_OR_REVERSE,
1766    R200_ROP_COPY_INVERTED,
1767    R200_ROP_OR_INVERTED,
1768    R200_ROP_NAND,
1769    R200_ROP_SET,
1770 };
1771
1772 static void r200LogicOpCode( struct gl_context *ctx, GLenum opcode )
1773 {
1774    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1775    GLuint rop = (GLuint)opcode - GL_CLEAR;
1776
1777    ASSERT( rop < 16 );
1778
1779    R200_STATECHANGE( rmesa, msk );
1780    rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = r200_rop_tab[rop];
1781 }
1782
1783 /* =============================================================
1784  * State enable/disable
1785  */
1786
1787 static void r200Enable( struct gl_context *ctx, GLenum cap, GLboolean state )
1788 {
1789    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1790    GLuint p, flag;
1791
1792    if ( R200_DEBUG & RADEON_STATE )
1793       fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1794                _mesa_lookup_enum_by_nr( cap ),
1795                state ? "GL_TRUE" : "GL_FALSE" );
1796
1797    switch ( cap ) {
1798       /* Fast track this one...
1799        */
1800    case GL_TEXTURE_1D:
1801    case GL_TEXTURE_2D:
1802    case GL_TEXTURE_3D:
1803       break;
1804
1805    case GL_ALPHA_TEST:
1806       R200_STATECHANGE( rmesa, ctx );
1807       if (state) {
1808          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ALPHA_TEST_ENABLE;
1809       } else {
1810          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ALPHA_TEST_ENABLE;
1811       }
1812       break;
1813
1814    case GL_BLEND:
1815    case GL_COLOR_LOGIC_OP:
1816       r200_set_blend_state( ctx );
1817       break;
1818
1819    case GL_CLIP_PLANE0:
1820    case GL_CLIP_PLANE1:
1821    case GL_CLIP_PLANE2:
1822    case GL_CLIP_PLANE3:
1823    case GL_CLIP_PLANE4:
1824    case GL_CLIP_PLANE5:
1825       p = cap-GL_CLIP_PLANE0;
1826       R200_STATECHANGE( rmesa, tcl );
1827       if (state) {
1828          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0<<p);
1829          r200ClipPlane( ctx, cap, NULL );
1830       }
1831       else {
1832          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0<<p);
1833       }
1834       break;
1835
1836    case GL_COLOR_MATERIAL:
1837       r200ColorMaterial( ctx, 0, 0 );
1838       r200UpdateMaterial( ctx );
1839       break;
1840
1841    case GL_CULL_FACE:
1842       r200CullFace( ctx, 0 );
1843       break;
1844
1845    case GL_DEPTH_TEST:
1846       R200_STATECHANGE(rmesa, ctx );
1847       if ( state ) {
1848          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_Z_ENABLE;
1849       } else {
1850          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_Z_ENABLE;
1851       }
1852       break;
1853
1854    case GL_DITHER:
1855       R200_STATECHANGE(rmesa, ctx );
1856       if ( state ) {
1857          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_DITHER_ENABLE;
1858          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1859       } else {
1860          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_DITHER_ENABLE;
1861          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  rmesa->radeon.state.color.roundEnable;
1862       }
1863       break;
1864
1865    case GL_FOG:
1866       R200_STATECHANGE(rmesa, ctx );
1867       if ( state ) {
1868          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_FOG_ENABLE;
1869          r200Fogfv( ctx, GL_FOG_MODE, NULL );
1870       } else {
1871          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_FOG_ENABLE;
1872          R200_STATECHANGE(rmesa, tcl);
1873          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK;
1874       }
1875       r200UpdateSpecular( ctx ); /* for PK_SPEC */
1876       if (rmesa->radeon.TclFallback)
1877          r200ChooseVertexState( ctx );
1878       _mesa_allow_light_in_model( ctx, !state );
1879       break;
1880
1881    case GL_LIGHT0:
1882    case GL_LIGHT1:
1883    case GL_LIGHT2:
1884    case GL_LIGHT3:
1885    case GL_LIGHT4:
1886    case GL_LIGHT5:
1887    case GL_LIGHT6:
1888    case GL_LIGHT7:
1889       R200_STATECHANGE(rmesa, tcl);
1890       p = cap - GL_LIGHT0;
1891       if (p&1)
1892          flag = (R200_LIGHT_1_ENABLE |
1893                  R200_LIGHT_1_ENABLE_AMBIENT |
1894                  R200_LIGHT_1_ENABLE_SPECULAR);
1895       else
1896          flag = (R200_LIGHT_0_ENABLE |
1897                  R200_LIGHT_0_ENABLE_AMBIENT |
1898                  R200_LIGHT_0_ENABLE_SPECULAR);
1899
1900       if (state)
1901          rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1902       else
1903          rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1904
1905       /*
1906        */
1907       update_light_colors( ctx, p );
1908       break;
1909
1910    case GL_LIGHTING:
1911       r200UpdateSpecular(ctx);
1912       /* for reflection map fixup - might set recheck_texgen for all units too */
1913       rmesa->radeon.NewGLState |= _NEW_TEXTURE;
1914       break;
1915
1916    case GL_LINE_SMOOTH:
1917       R200_STATECHANGE( rmesa, ctx );
1918       if ( state ) {
1919          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  R200_ANTI_ALIAS_LINE;
1920       } else {
1921          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_LINE;
1922       }
1923       break;
1924
1925    case GL_LINE_STIPPLE:
1926       R200_STATECHANGE( rmesa, set );
1927       if ( state ) {
1928          rmesa->hw.set.cmd[SET_RE_CNTL] |=  R200_PATTERN_ENABLE;
1929       } else {
1930          rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PATTERN_ENABLE;
1931       }
1932       break;
1933
1934    case GL_NORMALIZE:
1935       R200_STATECHANGE( rmesa, tcl );
1936       if ( state ) {
1937          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_NORMALIZE_NORMALS;
1938       } else {
1939          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_NORMALIZE_NORMALS;
1940       }
1941       break;
1942
1943       /* Pointsize registers on r200 only work for point sprites, and point smooth
1944        * doesn't work for point sprites (and isn't needed for 1.0 sized aa points).
1945        * In any case, setting pointmin == pointsizemax == 1.0 for aa points
1946        * is enough to satisfy conform.
1947        */
1948    case GL_POINT_SMOOTH:
1949       break;
1950
1951       /* These don't really do anything, as we don't use the 3vtx
1952        * primitives yet.
1953        */
1954 #if 0
1955    case GL_POLYGON_OFFSET_POINT:
1956       R200_STATECHANGE( rmesa, set );
1957       if ( state ) {
1958          rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_POINT;
1959       } else {
1960          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_POINT;
1961       }
1962       break;
1963
1964    case GL_POLYGON_OFFSET_LINE:
1965       R200_STATECHANGE( rmesa, set );
1966       if ( state ) {
1967          rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_LINE;
1968       } else {
1969          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_LINE;
1970       }
1971       break;
1972 #endif
1973
1974    case GL_POINT_SPRITE_ARB:
1975       R200_STATECHANGE( rmesa, spr );
1976       if ( state ) {
1977          int i;
1978          for (i = 0; i < 6; i++) {
1979             rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
1980                 ctx->Point.CoordReplace[i] << (R200_PS_GEN_TEX_0_SHIFT + i);
1981          }
1982       } else {
1983          rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~R200_PS_GEN_TEX_MASK;
1984       }
1985       break;
1986
1987    case GL_POLYGON_OFFSET_FILL:
1988       R200_STATECHANGE( rmesa, set );
1989       if ( state ) {
1990          rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_TRI;
1991       } else {
1992          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_TRI;
1993       }
1994       break;
1995
1996    case GL_POLYGON_SMOOTH:
1997       R200_STATECHANGE( rmesa, ctx );
1998       if ( state ) {
1999          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  R200_ANTI_ALIAS_POLY;
2000       } else {
2001          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_POLY;
2002       }
2003       break;
2004
2005    case GL_POLYGON_STIPPLE:
2006       R200_STATECHANGE(rmesa, set );
2007       if ( state ) {
2008          rmesa->hw.set.cmd[SET_RE_CNTL] |=  R200_STIPPLE_ENABLE;
2009       } else {
2010          rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_STIPPLE_ENABLE;
2011       }
2012       break;
2013
2014    case GL_RESCALE_NORMAL_EXT: {
2015       GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
2016       R200_STATECHANGE( rmesa, tcl );
2017       if ( tmp ) {
2018          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_RESCALE_NORMALS;
2019       } else {
2020          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
2021       }
2022       break;
2023    }
2024
2025    case GL_SCISSOR_TEST:
2026       radeon_firevertices(&rmesa->radeon);
2027       rmesa->radeon.state.scissor.enabled = state;
2028       radeonUpdateScissor( ctx );
2029       break;
2030
2031    case GL_STENCIL_TEST:
2032       {
2033          GLboolean hw_stencil = GL_FALSE;
2034          if (ctx->DrawBuffer) {
2035             struct radeon_renderbuffer *rrbStencil
2036                = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
2037             hw_stencil = (rrbStencil && rrbStencil->bo);
2038          }
2039
2040          if (hw_stencil) {
2041             R200_STATECHANGE( rmesa, ctx );
2042             if ( state ) {
2043                rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_STENCIL_ENABLE;
2044             } else {
2045                rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE;
2046             }
2047          } else {
2048             FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );
2049          }
2050       }
2051       break;
2052
2053    case GL_TEXTURE_GEN_Q:
2054    case GL_TEXTURE_GEN_R:
2055    case GL_TEXTURE_GEN_S:
2056    case GL_TEXTURE_GEN_T:
2057       /* Picked up in r200UpdateTextureState.
2058        */
2059       rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
2060       break;
2061
2062    case GL_COLOR_SUM_EXT:
2063       r200UpdateSpecular ( ctx );
2064       break;
2065
2066    case GL_VERTEX_PROGRAM_ARB:
2067       if (!state) {
2068          GLuint i;
2069          rmesa->curr_vp_hw = NULL;
2070          R200_STATECHANGE( rmesa, vap );
2071          rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_PROG_VTX_SHADER_ENABLE;
2072          /* mark all tcl atoms (tcl vector state got overwritten) dirty
2073             not sure about tcl scalar state - we need at least grd
2074             with vert progs too.
2075             ucp looks like it doesn't get overwritten (may even work
2076             with vp for pos-invariant progs if we're lucky) */
2077          R200_STATECHANGE( rmesa, mtl[0] );
2078          R200_STATECHANGE( rmesa, mtl[1] );
2079          R200_STATECHANGE( rmesa, fog );
2080          R200_STATECHANGE( rmesa, glt );
2081          R200_STATECHANGE( rmesa, eye );
2082          for (i = R200_MTX_MV; i <= R200_MTX_TEX5; i++) {
2083             R200_STATECHANGE( rmesa, mat[i] );
2084          }
2085          for (i = 0 ; i < 8; i++) {
2086             R200_STATECHANGE( rmesa, lit[i] );
2087          }
2088          R200_STATECHANGE( rmesa, tcl );
2089          for (i = 0; i <= ctx->Const.MaxClipPlanes; i++) {
2090             if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
2091                rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0 << i);
2092             }
2093 /*          else {
2094                rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0 << i);
2095             }*/
2096          }
2097          /* ugly. Need to call everything which might change compsel. */
2098          r200UpdateSpecular( ctx );
2099 #if 0
2100         /* shouldn't be necessary, as it's picked up anyway in r200ValidateState (_NEW_PROGRAM),
2101            but without it doom3 locks up at always the same places. Why? */
2102         /* FIXME: This can (and should) be replaced by a call to the TCL_STATE_FLUSH reg before
2103            accessing VAP_SE_VAP_CNTL. Requires drm changes (done). Remove after some time... */
2104          r200UpdateTextureState( ctx );
2105          /* if we call r200UpdateTextureState we need the code below because we are calling it with
2106             non-current derived enabled values which may revert the state atoms for frag progs even when
2107             they already got disabled... ugh
2108             Should really figure out why we need to call r200UpdateTextureState in the first place */
2109          GLuint unit;
2110          for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
2111             R200_STATECHANGE( rmesa, pix[unit] );
2112             R200_STATECHANGE( rmesa, tex[unit] );
2113             rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
2114                 ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
2115             rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
2116             /* need to guard this with drmSupportsFragmentShader? Should never get here if
2117                we don't announce ATI_fs, right? */
2118             rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
2119          }
2120          R200_STATECHANGE( rmesa, cst );
2121          R200_STATECHANGE( rmesa, tf );
2122          rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
2123 #endif
2124       }
2125       else {
2126          /* picked up later */
2127       }
2128       /* call functions which change hw state based on ARB_vp enabled or not. */
2129       r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
2130       r200Fogfv( ctx, GL_FOG_COORD_SRC, NULL );
2131       break;
2132
2133    case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
2134       r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
2135       break;
2136
2137    case GL_FRAGMENT_SHADER_ATI:
2138       if ( !state ) {
2139          /* restore normal tex env colors and make sure tex env combine will get updated
2140             mark env atoms dirty (as their data was overwritten by afs even
2141             if they didn't change) and restore tex coord routing */
2142          GLuint unit;
2143          for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
2144             R200_STATECHANGE( rmesa, pix[unit] );
2145             R200_STATECHANGE( rmesa, tex[unit] );
2146             rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
2147                 ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
2148             rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
2149             /* need to guard this with drmSupportsFragmentShader? Should never get here if
2150                we don't announce ATI_fs, right? */
2151             rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
2152          }
2153          R200_STATECHANGE( rmesa, cst );
2154          R200_STATECHANGE( rmesa, tf );
2155          rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
2156       }
2157       else {
2158          /* need to mark this dirty as pix/tf atoms have overwritten the data
2159             even if the data in the atoms didn't change */
2160          R200_STATECHANGE( rmesa, atf );
2161          R200_STATECHANGE( rmesa, afs[1] );
2162          /* everything else picked up in r200UpdateTextureState hopefully */
2163       }
2164       break;
2165    default:
2166       return;
2167    }
2168 }
2169
2170
2171 void r200LightingSpaceChange( struct gl_context *ctx )
2172 {
2173    r200ContextPtr rmesa = R200_CONTEXT(ctx);
2174    GLboolean tmp;
2175
2176    if (R200_DEBUG & RADEON_STATE)
2177       fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
2178               rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
2179
2180    if (ctx->_NeedEyeCoords)
2181       tmp = ctx->Transform.RescaleNormals;
2182    else
2183       tmp = !ctx->Transform.RescaleNormals;
2184
2185    R200_STATECHANGE( rmesa, tcl );
2186    if ( tmp ) {
2187       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_RESCALE_NORMALS;
2188    } else {
2189       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
2190    }
2191
2192    if (R200_DEBUG & RADEON_STATE)
2193       fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
2194               rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
2195 }
2196
2197 /* =============================================================
2198  * Deferred state management - matrices, textures, other?
2199  */
2200
2201
2202
2203
2204 static void upload_matrix( r200ContextPtr rmesa, GLfloat *src, int idx )
2205 {
2206    float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
2207    int i;
2208
2209
2210    for (i = 0 ; i < 4 ; i++) {
2211       *dest++ = src[i];
2212       *dest++ = src[i+4];
2213       *dest++ = src[i+8];
2214       *dest++ = src[i+12];
2215    }
2216
2217    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2218 }
2219
2220 static void upload_matrix_t( r200ContextPtr rmesa, const GLfloat *src, int idx )
2221 {
2222    float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
2223    memcpy(dest, src, 16*sizeof(float));
2224    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2225 }
2226
2227
2228 static void update_texturematrix( struct gl_context *ctx )
2229 {
2230    r200ContextPtr rmesa = R200_CONTEXT( ctx );
2231    GLuint tpc = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0];
2232    GLuint compsel = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL];
2233    int unit;
2234
2235    if (R200_DEBUG & RADEON_STATE)
2236       fprintf(stderr, "%s before COMPSEL: %x\n", __FUNCTION__,
2237               rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]);
2238
2239    rmesa->TexMatEnabled = 0;
2240    rmesa->TexMatCompSel = 0;
2241
2242    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
2243       if (!ctx->Texture.Unit[unit]._ReallyEnabled)
2244          continue;
2245
2246       if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2247          rmesa->TexMatEnabled |= (R200_TEXGEN_TEXMAT_0_ENABLE|
2248                                   R200_TEXMAT_0_ENABLE) << unit;
2249
2250          rmesa->TexMatCompSel |= R200_OUTPUT_TEX_0 << unit;
2251
2252          if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
2253             /* Need to preconcatenate any active texgen
2254              * obj/eyeplane matrices:
2255              */
2256             _math_matrix_mul_matrix( &rmesa->tmpmat,
2257                                      ctx->TextureMatrixStack[unit].Top,
2258                                      &rmesa->TexGenMatrix[unit] );
2259             upload_matrix( rmesa, rmesa->tmpmat.m, R200_MTX_TEX0+unit );
2260          }
2261          else {
2262             upload_matrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,
2263                            R200_MTX_TEX0+unit );
2264          }
2265       }
2266       else if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
2267          upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m,
2268                         R200_MTX_TEX0+unit );
2269       }
2270    }
2271
2272    tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
2273    if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0]) {
2274       R200_STATECHANGE(rmesa, tcg);
2275       rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = tpc;
2276    }
2277
2278    compsel &= ~R200_OUTPUT_TEX_MASK;
2279    compsel |= rmesa->TexMatCompSel | rmesa->TexGenCompSel;
2280    if (compsel != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]) {
2281       R200_STATECHANGE(rmesa, vtx);
2282       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = compsel;
2283    }
2284 }
2285
2286 static GLboolean r200ValidateBuffers(struct gl_context *ctx)
2287 {
2288    r200ContextPtr rmesa = R200_CONTEXT(ctx);
2289    struct radeon_renderbuffer *rrb;
2290    struct radeon_dma_bo *dma_bo;
2291    int i, ret;
2292
2293         if (RADEON_DEBUG & RADEON_IOCTL)
2294                 fprintf(stderr, "%s\n", __FUNCTION__);
2295    radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2296
2297    rrb = radeon_get_colorbuffer(&rmesa->radeon);
2298    /* color buffer */
2299    if (rrb && rrb->bo) {
2300      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2301                                        0, RADEON_GEM_DOMAIN_VRAM);
2302    }
2303
2304    /* depth buffer */
2305    rrb = radeon_get_depthbuffer(&rmesa->radeon);
2306    /* color buffer */
2307    if (rrb && rrb->bo) {
2308      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2309                                        0, RADEON_GEM_DOMAIN_VRAM);
2310    }
2311
2312    for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
2313       radeonTexObj *t;
2314
2315       if (!ctx->Texture.Unit[i]._ReallyEnabled)
2316          continue;
2317
2318       t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
2319       if (t->image_override && t->bo)
2320         radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2321                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2322       else if (t->mt->bo)
2323         radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2324                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2325    }
2326
2327    dma_bo = first_elem(&rmesa->radeon.dma.reserved);
2328    {
2329        ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, dma_bo->bo, RADEON_GEM_DOMAIN_GTT, 0);
2330        if (ret)
2331            return GL_FALSE;
2332    }
2333    return GL_TRUE;
2334 }
2335
2336 GLboolean r200ValidateState( struct gl_context *ctx )
2337 {
2338    r200ContextPtr rmesa = R200_CONTEXT(ctx);
2339    GLuint new_state = rmesa->radeon.NewGLState;
2340
2341    if (new_state & _NEW_BUFFERS) {
2342       _mesa_update_framebuffer(ctx);
2343       /* this updates the DrawBuffer's Width/Height if it's a FBO */
2344       _mesa_update_draw_buffer_bounds(ctx);
2345
2346       R200_STATECHANGE(rmesa, ctx);
2347    }
2348
2349    if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)) {
2350       r200UpdateTextureState( ctx );
2351       new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2352       r200UpdateLocalViewer( ctx );
2353    }
2354
2355    /* we need to do a space check here */
2356    if (!r200ValidateBuffers(ctx))
2357      return GL_FALSE;
2358
2359 /* FIXME: don't really need most of these when vertex progs are enabled */
2360
2361    /* Need an event driven matrix update?
2362     */
2363    if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2364       upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, R200_MTX_MVP );
2365
2366    /* Need these for lighting (shouldn't upload otherwise)
2367     */
2368    if (new_state & (_NEW_MODELVIEW)) {
2369       upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, R200_MTX_MV );
2370       upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, R200_MTX_IMV );
2371    }
2372
2373    /* Does this need to be triggered on eg. modelview for
2374     * texgen-derived objplane/eyeplane matrices?
2375     */
2376    if (new_state & (_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) {
2377       update_texturematrix( ctx );
2378    }
2379
2380    if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2381       update_light( ctx );
2382    }
2383
2384    /* emit all active clip planes if projection matrix changes.
2385     */
2386    if (new_state & (_NEW_PROJECTION)) {
2387       if (ctx->Transform.ClipPlanesEnabled)
2388          r200UpdateClipPlanes( ctx );
2389    }
2390
2391    if (new_state & (_NEW_PROGRAM|
2392                     _NEW_PROGRAM_CONSTANTS |
2393    /* need to test for pretty much anything due to possible parameter bindings */
2394         _NEW_MODELVIEW|_NEW_PROJECTION|_NEW_TRANSFORM|
2395         _NEW_LIGHT|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX|
2396         _NEW_FOG|_NEW_POINT|_NEW_TRACK_MATRIX)) {
2397       if (ctx->VertexProgram._Enabled) {
2398          r200SetupVertexProg( ctx );
2399       }
2400       else TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, 0);
2401    }
2402
2403    rmesa->radeon.NewGLState = 0;
2404    return GL_TRUE;
2405 }
2406
2407
2408 static void r200InvalidateState( struct gl_context *ctx, GLuint new_state )
2409 {
2410    _swrast_InvalidateState( ctx, new_state );
2411    _swsetup_InvalidateState( ctx, new_state );
2412    _vbo_InvalidateState( ctx, new_state );
2413    _tnl_InvalidateState( ctx, new_state );
2414    _ae_invalidate_state( ctx, new_state );
2415    R200_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2416 }
2417
2418 /* A hack.  The r200 can actually cope just fine with materials
2419  * between begin/ends, so fix this.
2420  * Should map to inputs just like the generic vertex arrays for vertex progs.
2421  * In theory there could still be too many and we'd still need a fallback.
2422  */
2423 static GLboolean check_material( struct gl_context *ctx )
2424 {
2425    TNLcontext *tnl = TNL_CONTEXT(ctx);
2426    GLint i;
2427
2428    for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2429         i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2430         i++)
2431       if (tnl->vb.AttribPtr[i] &&
2432           tnl->vb.AttribPtr[i]->stride)
2433          return GL_TRUE;
2434
2435    return GL_FALSE;
2436 }
2437
2438 static void r200WrapRunPipeline( struct gl_context *ctx )
2439 {
2440    r200ContextPtr rmesa = R200_CONTEXT(ctx);
2441    GLboolean has_material;
2442
2443    if (0)
2444       fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2445
2446    /* Validate state:
2447     */
2448    if (rmesa->radeon.NewGLState)
2449       if (!r200ValidateState( ctx ))
2450          FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2451
2452    has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx );
2453
2454    if (has_material) {
2455       TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE );
2456    }
2457
2458    /* Run the pipeline.
2459     */
2460    _tnl_run_pipeline( ctx );
2461
2462    if (has_material) {
2463       TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_FALSE );
2464    }
2465 }
2466
2467
2468 static void r200PolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2469 {
2470    r200ContextPtr r200 = R200_CONTEXT(ctx);
2471    GLint i;
2472
2473    radeon_firevertices(&r200->radeon);
2474
2475    radeon_print(RADEON_STATE, RADEON_TRACE,
2476                    "%s(%p) first 32 bits are %x.\n",
2477                    __func__,
2478                    ctx,
2479                    *(uint32_t*)mask);
2480
2481    R200_STATECHANGE(r200, stp);
2482
2483    /* Must flip pattern upside down.
2484     */
2485    for ( i = 31 ; i >= 0; i--) {
2486      r200->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2487    }
2488 }
2489 /* Initialize the driver's state functions.
2490  */
2491 void r200InitStateFuncs( radeonContextPtr radeon, struct dd_function_table *functions )
2492 {
2493    functions->UpdateState               = r200InvalidateState;
2494    functions->LightingSpaceChange       = r200LightingSpaceChange;
2495
2496    functions->DrawBuffer                = radeonDrawBuffer;
2497    functions->ReadBuffer                = radeonReadBuffer;
2498
2499    functions->CopyPixels                = _mesa_meta_CopyPixels;
2500    functions->DrawPixels                = _mesa_meta_DrawPixels;
2501    if (radeon->radeonScreen->kernel_mm)
2502            functions->ReadPixels                = radeonReadPixels;
2503
2504    functions->AlphaFunc                 = r200AlphaFunc;
2505    functions->BlendColor                = r200BlendColor;
2506    functions->BlendEquationSeparate     = r200BlendEquationSeparate;
2507    functions->BlendFuncSeparate         = r200BlendFuncSeparate;
2508    functions->ClearColor                = r200ClearColor;
2509    functions->ClearDepth                = r200ClearDepth;
2510    functions->ClearStencil              = r200ClearStencil;
2511    functions->ClipPlane                 = r200ClipPlane;
2512    functions->ColorMask                 = r200ColorMask;
2513    functions->CullFace                  = r200CullFace;
2514    functions->DepthFunc                 = r200DepthFunc;
2515    functions->DepthMask                 = r200DepthMask;
2516    functions->DepthRange                = r200DepthRange;
2517    functions->Enable                    = r200Enable;
2518    functions->Fogfv                     = r200Fogfv;
2519    functions->FrontFace                 = r200FrontFace;
2520    functions->Hint                      = NULL;
2521    functions->LightModelfv              = r200LightModelfv;
2522    functions->Lightfv                   = r200Lightfv;
2523    functions->LineStipple               = r200LineStipple;
2524    functions->LineWidth                 = r200LineWidth;
2525    functions->LogicOpcode               = r200LogicOpCode;
2526    functions->PolygonMode               = r200PolygonMode;
2527    functions->PolygonOffset             = r200PolygonOffset;
2528    functions->PolygonStipple            = r200PolygonStipple;
2529    functions->PointParameterfv          = r200PointParameter;
2530    functions->PointSize                 = r200PointSize;
2531    functions->RenderMode                = r200RenderMode;
2532    functions->Scissor                   = radeonScissor;
2533    functions->ShadeModel                = r200ShadeModel;
2534    functions->StencilFuncSeparate       = r200StencilFuncSeparate;
2535    functions->StencilMaskSeparate       = r200StencilMaskSeparate;
2536    functions->StencilOpSeparate         = r200StencilOpSeparate;
2537    functions->Viewport                  = r200Viewport;
2538 }
2539
2540
2541 void r200InitTnlFuncs( struct gl_context *ctx )
2542 {
2543    TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = r200UpdateMaterial;
2544    TNL_CONTEXT(ctx)->Driver.RunPipeline = r200WrapRunPipeline;
2545 }