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