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_COORD_ORIGIN: */
634    default:
635       fprintf(stderr, "bad pname parameter in r200PointParameter\n");
636       return;
637    }
638 }
639 
640 /* =============================================================
641  * Line state
642  */
r200LineWidth(struct gl_context * ctx,GLfloat widthf)643 static void r200LineWidth( struct gl_context *ctx, GLfloat widthf )
644 {
645    r200ContextPtr rmesa = R200_CONTEXT(ctx);
646 
647    R200_STATECHANGE( rmesa, lin );
648    R200_STATECHANGE( rmesa, set );
649 
650    /* Line width is stored in U6.4 format.
651     * Same min/max limits for AA, non-AA lines.
652     */
653    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff;
654    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)
655       (CLAMP(widthf, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth) * 16.0);
656 
657    if ( widthf > 1.0 ) {
658       rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_WIDELINE_ENABLE;
659    } else {
660       rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_WIDELINE_ENABLE;
661    }
662 }
663 
r200LineStipple(struct gl_context * ctx,GLint factor,GLushort pattern)664 static void r200LineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
665 {
666    r200ContextPtr rmesa = R200_CONTEXT(ctx);
667 
668    R200_STATECHANGE( rmesa, lin );
669    rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
670       ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
671 }
672 
673 
674 /* =============================================================
675  * Masks
676  */
r200ColorMask(struct gl_context * ctx,GLboolean r,GLboolean g,GLboolean b,GLboolean a)677 static void r200ColorMask( struct gl_context *ctx,
678 			   GLboolean r, GLboolean g,
679 			   GLboolean b, GLboolean a )
680 {
681    r200ContextPtr rmesa = R200_CONTEXT(ctx);
682    GLuint mask;
683    struct radeon_renderbuffer *rrb;
684    GLuint flag = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & ~R200_PLANE_MASK_ENABLE;
685 
686    rrb = radeon_get_colorbuffer(&rmesa->radeon);
687    if (!rrb)
688      return;
689    mask = radeonPackColor( rrb->cpp,
690 			   GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 0)*0xFF,
691 			   GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 1)*0xFF,
692 			   GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 2)*0xFF,
693 			   GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 3)*0xFF );
694 
695 
696    if (!(r && g && b && a))
697       flag |= R200_PLANE_MASK_ENABLE;
698 
699    if ( rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] != flag ) {
700       R200_STATECHANGE( rmesa, ctx );
701       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = flag;
702    }
703 
704    if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
705       R200_STATECHANGE( rmesa, msk );
706       rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
707    }
708 }
709 
710 
711 /* =============================================================
712  * Polygon state
713  */
714 
r200PolygonOffset(struct gl_context * ctx,GLfloat factor,GLfloat units,GLfloat clamp)715 static void r200PolygonOffset( struct gl_context *ctx,
716 			       GLfloat factor, GLfloat units, GLfloat clamp )
717 {
718    r200ContextPtr rmesa = R200_CONTEXT(ctx);
719    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
720    float_ui32_type constant =  { units * depthScale };
721    float_ui32_type factoru = { factor };
722 
723 /*    factor *= 2; */
724 /*    constant *= 2; */
725 
726 /*    fprintf(stderr, "%s f:%f u:%f\n", __func__, factor, constant); */
727 
728    R200_STATECHANGE( rmesa, zbs );
729    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR]   = factoru.ui32;
730    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
731 }
732 
r200PolygonMode(struct gl_context * ctx,GLenum face,GLenum mode)733 static void r200PolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
734 {
735    r200ContextPtr rmesa = R200_CONTEXT(ctx);
736    GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
737                          ctx->Polygon.BackMode != GL_FILL);
738 
739    /* Can't generally do unfilled via tcl, but some good special
740     * cases work.
741     */
742    TCL_FALLBACK( ctx, R200_TCL_FALLBACK_UNFILLED, unfilled);
743    if (rmesa->radeon.TclFallback) {
744       r200ChooseRenderState( ctx );
745       r200ChooseVertexState( ctx );
746    }
747 }
748 
749 
750 /* =============================================================
751  * Rendering attributes
752  *
753  * We really don't want to recalculate all this every time we bind a
754  * texture.  These things shouldn't change all that often, so it makes
755  * sense to break them out of the core texture state update routines.
756  */
757 
758 /* Examine lighting and texture state to determine if separate specular
759  * should be enabled.
760  */
r200UpdateSpecular(struct gl_context * ctx)761 static void r200UpdateSpecular( struct gl_context *ctx )
762 {
763    r200ContextPtr rmesa = R200_CONTEXT(ctx);
764    uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
765 
766    R200_STATECHANGE( rmesa, tcl );
767    R200_STATECHANGE( rmesa, vtx );
768 
769    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_0_SHIFT);
770    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_1_SHIFT);
771    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_0;
772    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_1;
773    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHTING_ENABLE;
774 
775    p &= ~R200_SPECULAR_ENABLE;
776 
777    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_DIFFUSE_SPECULAR_COMBINE;
778 
779 
780    if (ctx->Light.Enabled &&
781        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
782       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
783 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
784 	  (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
785       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
786       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
787       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
788       p |=  R200_SPECULAR_ENABLE;
789       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &=
790 	 ~R200_DIFFUSE_SPECULAR_COMBINE;
791    }
792    else if (ctx->Light.Enabled) {
793       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
794 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
795       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
796       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
797    } else if (ctx->Fog.ColorSumEnabled ) {
798       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
799 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
800 	  (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
801       p |=  R200_SPECULAR_ENABLE;
802    } else {
803       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
804 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
805    }
806 
807    if (ctx->Fog.Enabled) {
808       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
809 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
810       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
811    }
812 
813    if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
814       R200_STATECHANGE( rmesa, ctx );
815       rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
816    }
817 
818    /* Update vertex/render formats
819     */
820    if (rmesa->radeon.TclFallback) {
821       r200ChooseRenderState( ctx );
822       r200ChooseVertexState( ctx );
823    }
824 }
825 
826 
827 /* =============================================================
828  * Materials
829  */
830 
831 
832 /* Update on colormaterial, material emmissive/ambient,
833  * lightmodel.globalambient
834  */
update_global_ambient(struct gl_context * ctx)835 static void update_global_ambient( struct gl_context *ctx )
836 {
837    r200ContextPtr rmesa = R200_CONTEXT(ctx);
838    float *fcmd = (float *)R200_DB_STATE( glt );
839 
840    /* Need to do more if both emmissive & ambient are PREMULT:
841     * I believe this is not nessary when using source_material. This condition thus
842     * will never happen currently, and the function has no dependencies on materials now
843     */
844    if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] &
845        ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
846 	(3 << R200_FRONT_AMBIENT_SOURCE_SHIFT))) == 0)
847    {
848       COPY_3V( &fcmd[GLT_RED],
849 	       ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
850       ACC_SCALE_3V( &fcmd[GLT_RED],
851 		   ctx->Light.Model.Ambient,
852 		   ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
853    }
854    else
855    {
856       COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
857    }
858 
859    R200_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
860 }
861 
862 /* Update on change to
863  *    - light[p].colors
864  *    - light[p].enabled
865  */
update_light_colors(struct gl_context * ctx,GLuint p)866 static void update_light_colors( struct gl_context *ctx, GLuint p )
867 {
868    struct gl_light *l = &ctx->Light.Light[p];
869    struct gl_light_uniforms *lu = &ctx->Light.LightSource[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], lu->Ambient );
878       COPY_4V( &fcmd[LIT_DIFFUSE_RED], lu->Diffuse );
879       COPY_4V( &fcmd[LIT_SPECULAR_RED], lu->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          struct gl_light_uniforms *lu = &ctx->Light.LightSource[p];
1122          GLfloat *fcmd = (GLfloat *)R200_DB_STATE( lit[p] );
1123 
1124          if (lu->EyePosition[3] == 0.0) {
1125             COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
1126             COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
1127             fcmd[LIT_POSITION_W] = 0;
1128             fcmd[LIT_DIRECTION_W] = 0;
1129          } else {
1130             COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
1131             fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
1132             fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
1133             fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
1134             fcmd[LIT_DIRECTION_W] = 0;
1135          }
1136 
1137          R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
1138       }
1139    }
1140 }
1141 
r200Lightfv(struct gl_context * ctx,GLenum light,GLenum pname,const GLfloat * params)1142 static void r200Lightfv( struct gl_context *ctx, GLenum light,
1143 			   GLenum pname, const GLfloat *params )
1144 {
1145    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1146    GLint p = light - GL_LIGHT0;
1147    struct gl_light_uniforms *lu = &ctx->Light.LightSource[p];
1148    GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
1149 
1150 
1151    switch (pname) {
1152    case GL_AMBIENT:
1153    case GL_DIFFUSE:
1154    case GL_SPECULAR:
1155       update_light_colors( ctx, p );
1156       break;
1157 
1158    case GL_SPOT_DIRECTION:
1159       /* picked up in update_light */
1160       break;
1161 
1162    case GL_POSITION: {
1163       /* positions picked up in update_light, but can do flag here */
1164       GLuint flag = (p&1)? R200_LIGHT_1_IS_LOCAL : R200_LIGHT_0_IS_LOCAL;
1165       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1166 
1167       R200_STATECHANGE(rmesa, tcl);
1168       if (lu->EyePosition[3] != 0.0F)
1169 	 rmesa->hw.tcl.cmd[idx] |= flag;
1170       else
1171 	 rmesa->hw.tcl.cmd[idx] &= ~flag;
1172       break;
1173    }
1174 
1175    case GL_SPOT_EXPONENT:
1176       R200_STATECHANGE(rmesa, lit[p]);
1177       fcmd[LIT_SPOT_EXPONENT] = params[0];
1178       break;
1179 
1180    case GL_SPOT_CUTOFF: {
1181       GLuint flag = (p&1) ? R200_LIGHT_1_IS_SPOT : R200_LIGHT_0_IS_SPOT;
1182       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1183 
1184       R200_STATECHANGE(rmesa, lit[p]);
1185       fcmd[LIT_SPOT_CUTOFF] = lu->_CosCutoff;
1186 
1187       R200_STATECHANGE(rmesa, tcl);
1188       if (lu->SpotCutoff != 180.0F)
1189 	 rmesa->hw.tcl.cmd[idx] |= flag;
1190       else
1191 	 rmesa->hw.tcl.cmd[idx] &= ~flag;
1192 
1193       break;
1194    }
1195 
1196    case GL_CONSTANT_ATTENUATION:
1197       R200_STATECHANGE(rmesa, lit[p]);
1198       fcmd[LIT_ATTEN_CONST] = params[0];
1199       if ( params[0] == 0.0 )
1200 	 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
1201       else
1202 	 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
1203       break;
1204    case GL_LINEAR_ATTENUATION:
1205       R200_STATECHANGE(rmesa, lit[p]);
1206       fcmd[LIT_ATTEN_LINEAR] = params[0];
1207       break;
1208    case GL_QUADRATIC_ATTENUATION:
1209       R200_STATECHANGE(rmesa, lit[p]);
1210       fcmd[LIT_ATTEN_QUADRATIC] = params[0];
1211       break;
1212    default:
1213       return;
1214    }
1215 
1216    /* Set RANGE_ATTEN only when needed */
1217    switch (pname) {
1218    case GL_POSITION:
1219    case GL_CONSTANT_ATTENUATION:
1220    case GL_LINEAR_ATTENUATION:
1221    case GL_QUADRATIC_ATTENUATION: {
1222       GLuint *icmd = (GLuint *)R200_DB_STATE( tcl );
1223       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1224       GLuint atten_flag = ( p&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN
1225 				  : R200_LIGHT_0_ENABLE_RANGE_ATTEN;
1226       GLuint atten_const_flag = ( p&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN
1227 				  : R200_LIGHT_0_CONSTANT_RANGE_ATTEN;
1228 
1229       if ( lu->EyePosition[3] == 0.0F ||
1230 	   ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1231 	     fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1232 	 /* Disable attenuation */
1233 	 icmd[idx] &= ~atten_flag;
1234       } else {
1235 	 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1236 	    /* Enable only constant portion of attenuation calculation */
1237 	    icmd[idx] |= ( atten_flag | atten_const_flag );
1238 	 } else {
1239 	    /* Enable full attenuation calculation */
1240 	    icmd[idx] &= ~atten_const_flag;
1241 	    icmd[idx] |= atten_flag;
1242 	 }
1243       }
1244 
1245       R200_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1246       break;
1247    }
1248    default:
1249      break;
1250    }
1251 }
1252 
r200UpdateLocalViewer(struct gl_context * ctx)1253 static void r200UpdateLocalViewer ( struct gl_context *ctx )
1254 {
1255 /* It looks like for the texgen modes GL_SPHERE_MAP, GL_NORMAL_MAP and
1256    GL_REFLECTION_MAP we need R200_LOCAL_VIEWER set (fglrx does exactly that
1257    for these and only these modes). This means specular highlights may turn out
1258    wrong in some cases when lighting is enabled but GL_LIGHT_MODEL_LOCAL_VIEWER
1259    is not set, though it seems to happen rarely and the effect seems quite
1260    subtle. May need TCL fallback to fix it completely, though I'm not sure
1261    how you'd identify the cases where the specular highlights indeed will
1262    be wrong. Don't know if fglrx does something special in that case.
1263 */
1264    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1265    R200_STATECHANGE( rmesa, tcl );
1266    if (ctx->Light.Model.LocalViewer ||
1267        ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
1268       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LOCAL_VIEWER;
1269    else
1270       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LOCAL_VIEWER;
1271 }
1272 
r200LightModelfv(struct gl_context * ctx,GLenum pname,const GLfloat * param)1273 static void r200LightModelfv( struct gl_context *ctx, GLenum pname,
1274 				const GLfloat *param )
1275 {
1276    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1277 
1278    switch (pname) {
1279       case GL_LIGHT_MODEL_AMBIENT:
1280 	 update_global_ambient( ctx );
1281 	 break;
1282 
1283       case GL_LIGHT_MODEL_LOCAL_VIEWER:
1284 	 r200UpdateLocalViewer( ctx );
1285          break;
1286 
1287       case GL_LIGHT_MODEL_TWO_SIDE:
1288 	 R200_STATECHANGE( rmesa, tcl );
1289 	 if (ctx->Light.Model.TwoSide)
1290 	    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHT_TWOSIDE;
1291 	 else
1292 	    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~(R200_LIGHT_TWOSIDE);
1293 	 if (rmesa->radeon.TclFallback) {
1294 	    r200ChooseRenderState( ctx );
1295 	    r200ChooseVertexState( ctx );
1296 	 }
1297          break;
1298 
1299       case GL_LIGHT_MODEL_COLOR_CONTROL:
1300 	 r200UpdateSpecular(ctx);
1301          break;
1302 
1303       default:
1304          break;
1305    }
1306 }
1307 
r200ShadeModel(struct gl_context * ctx,GLenum mode)1308 static void r200ShadeModel( struct gl_context *ctx, GLenum mode )
1309 {
1310    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1311    GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1312 
1313    s &= ~(R200_DIFFUSE_SHADE_MASK |
1314 	  R200_ALPHA_SHADE_MASK |
1315 	  R200_SPECULAR_SHADE_MASK |
1316 	  R200_FOG_SHADE_MASK |
1317 	  R200_DISC_FOG_SHADE_MASK);
1318 
1319    switch ( mode ) {
1320    case GL_FLAT:
1321       s |= (R200_DIFFUSE_SHADE_FLAT |
1322 	    R200_ALPHA_SHADE_FLAT |
1323 	    R200_SPECULAR_SHADE_FLAT |
1324 	    R200_FOG_SHADE_FLAT |
1325 	    R200_DISC_FOG_SHADE_FLAT);
1326       break;
1327    case GL_SMOOTH:
1328       s |= (R200_DIFFUSE_SHADE_GOURAUD |
1329 	    R200_ALPHA_SHADE_GOURAUD |
1330 	    R200_SPECULAR_SHADE_GOURAUD |
1331 	    R200_FOG_SHADE_GOURAUD |
1332 	    R200_DISC_FOG_SHADE_GOURAUD);
1333       break;
1334    default:
1335       return;
1336    }
1337 
1338    if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1339       R200_STATECHANGE( rmesa, set );
1340       rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1341    }
1342 }
1343 
1344 
1345 /* =============================================================
1346  * User clip planes
1347  */
1348 
r200ClipPlane(struct gl_context * ctx,GLenum plane,const GLfloat * eq)1349 static void r200ClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1350 {
1351    GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1352    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1353    GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1354 
1355    R200_STATECHANGE( rmesa, ucp[p] );
1356    rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1357    rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1358    rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1359    rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1360 }
1361 
r200UpdateClipPlanes(struct gl_context * ctx)1362 static void r200UpdateClipPlanes( struct gl_context *ctx )
1363 {
1364    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1365    GLbitfield mask = ctx->Transform.ClipPlanesEnabled;
1366 
1367    while (mask) {
1368       const int p = u_bit_scan(&mask);
1369       GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1370 
1371       R200_STATECHANGE( rmesa, ucp[p] );
1372       rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1373       rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1374       rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1375       rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1376    }
1377 }
1378 
1379 
1380 /* =============================================================
1381  * Stencil
1382  */
1383 
1384 static void
r200StencilFuncSeparate(struct gl_context * ctx,GLenum face,GLenum func,GLint ref,GLuint mask)1385 r200StencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1386                          GLint ref, GLuint mask )
1387 {
1388    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1389    GLuint refmask = ((_mesa_get_stencil_ref(ctx, 0) << R200_STENCIL_REF_SHIFT) |
1390 		     ((ctx->Stencil.ValueMask[0] & 0xff) << R200_STENCIL_MASK_SHIFT));
1391 
1392    R200_STATECHANGE( rmesa, ctx );
1393    R200_STATECHANGE( rmesa, msk );
1394 
1395    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_STENCIL_TEST_MASK;
1396    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(R200_STENCIL_REF_MASK|
1397 						   R200_STENCIL_VALUE_MASK);
1398 
1399    switch ( ctx->Stencil.Function[0] ) {
1400    case GL_NEVER:
1401       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEVER;
1402       break;
1403    case GL_LESS:
1404       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LESS;
1405       break;
1406    case GL_EQUAL:
1407       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_EQUAL;
1408       break;
1409    case GL_LEQUAL:
1410       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LEQUAL;
1411       break;
1412    case GL_GREATER:
1413       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GREATER;
1414       break;
1415    case GL_NOTEQUAL:
1416       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEQUAL;
1417       break;
1418    case GL_GEQUAL:
1419       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GEQUAL;
1420       break;
1421    case GL_ALWAYS:
1422       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_ALWAYS;
1423       break;
1424    }
1425 
1426    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1427 }
1428 
1429 static void
r200StencilMaskSeparate(struct gl_context * ctx,GLenum face,GLuint mask)1430 r200StencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1431 {
1432    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1433 
1434    R200_STATECHANGE( rmesa, msk );
1435    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~R200_STENCIL_WRITE_MASK;
1436    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1437       ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT);
1438 }
1439 
1440 static void
r200StencilOpSeparate(struct gl_context * ctx,GLenum face,GLenum fail,GLenum zfail,GLenum zpass)1441 r200StencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1442                        GLenum zfail, GLenum zpass )
1443 {
1444    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1445 
1446    R200_STATECHANGE( rmesa, ctx );
1447    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(R200_STENCIL_FAIL_MASK |
1448 					       R200_STENCIL_ZFAIL_MASK |
1449 					       R200_STENCIL_ZPASS_MASK);
1450 
1451    switch ( ctx->Stencil.FailFunc[0] ) {
1452    case GL_KEEP:
1453       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_KEEP;
1454       break;
1455    case GL_ZERO:
1456       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_ZERO;
1457       break;
1458    case GL_REPLACE:
1459       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_REPLACE;
1460       break;
1461    case GL_INCR:
1462       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC;
1463       break;
1464    case GL_DECR:
1465       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC;
1466       break;
1467    case GL_INCR_WRAP_EXT:
1468       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC_WRAP;
1469       break;
1470    case GL_DECR_WRAP_EXT:
1471       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC_WRAP;
1472       break;
1473    case GL_INVERT:
1474       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INVERT;
1475       break;
1476    }
1477 
1478    switch ( ctx->Stencil.ZFailFunc[0] ) {
1479    case GL_KEEP:
1480       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_KEEP;
1481       break;
1482    case GL_ZERO:
1483       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_ZERO;
1484       break;
1485    case GL_REPLACE:
1486       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_REPLACE;
1487       break;
1488    case GL_INCR:
1489       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC;
1490       break;
1491    case GL_DECR:
1492       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC;
1493       break;
1494    case GL_INCR_WRAP_EXT:
1495       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC_WRAP;
1496       break;
1497    case GL_DECR_WRAP_EXT:
1498       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC_WRAP;
1499       break;
1500    case GL_INVERT:
1501       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INVERT;
1502       break;
1503    }
1504 
1505    switch ( ctx->Stencil.ZPassFunc[0] ) {
1506    case GL_KEEP:
1507       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_KEEP;
1508       break;
1509    case GL_ZERO:
1510       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_ZERO;
1511       break;
1512    case GL_REPLACE:
1513       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_REPLACE;
1514       break;
1515    case GL_INCR:
1516       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC;
1517       break;
1518    case GL_DECR:
1519       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC;
1520       break;
1521    case GL_INCR_WRAP_EXT:
1522       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC_WRAP;
1523       break;
1524    case GL_DECR_WRAP_EXT:
1525       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC_WRAP;
1526       break;
1527    case GL_INVERT:
1528       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INVERT;
1529       break;
1530    }
1531 }
1532 
1533 
1534 /* =============================================================
1535  * Window position and viewport transformation
1536  */
1537 
1538 /**
1539  * Called when window size or position changes or viewport or depth range
1540  * state is changed.  We update the hardware viewport state here.
1541  */
r200UpdateWindow(struct gl_context * ctx)1542 void r200UpdateWindow( struct gl_context *ctx )
1543 {
1544    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1545    __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1546    GLfloat xoffset = 0;
1547    GLfloat yoffset = dPriv ? (GLfloat) dPriv->h : 0;
1548    const GLboolean render_to_fbo = (ctx->DrawBuffer ? _mesa_is_user_fbo(ctx->DrawBuffer) : 0);
1549    float scale[3], translate[3];
1550    GLfloat y_scale, y_bias;
1551 
1552    if (render_to_fbo) {
1553       y_scale = 1.0;
1554       y_bias = 0;
1555    } else {
1556       y_scale = -1.0;
1557       y_bias = yoffset;
1558    }
1559 
1560    _mesa_get_viewport_xform(ctx, 0, scale, translate);
1561    float_ui32_type sx = { scale[0] };
1562    float_ui32_type sy = { scale[1] * y_scale };
1563    float_ui32_type sz = { scale[2] };
1564    float_ui32_type tx = { translate[0] + xoffset };
1565    float_ui32_type ty = { (translate[1] * y_scale) + y_bias };
1566    float_ui32_type tz = { translate[2] };
1567 
1568    R200_STATECHANGE( rmesa, vpt );
1569 
1570    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = sx.ui32;
1571    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1572    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE]  = sy.ui32;
1573    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1574    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE]  = sz.ui32;
1575    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1576 }
1577 
r200_vtbl_update_scissor(struct gl_context * ctx)1578 void r200_vtbl_update_scissor( struct gl_context *ctx )
1579 {
1580    r200ContextPtr r200 = R200_CONTEXT(ctx);
1581    unsigned x1, y1, x2, y2;
1582    struct radeon_renderbuffer *rrb;
1583 
1584    R200_SET_STATE(r200, set, SET_RE_CNTL, R200_SCISSOR_ENABLE | r200->hw.set.cmd[SET_RE_CNTL]);
1585 
1586    if (r200->radeon.state.scissor.enabled) {
1587       x1 = r200->radeon.state.scissor.rect.x1;
1588       y1 = r200->radeon.state.scissor.rect.y1;
1589       x2 = r200->radeon.state.scissor.rect.x2;
1590       y2 = r200->radeon.state.scissor.rect.y2;
1591    } else {
1592       rrb = radeon_get_colorbuffer(&r200->radeon);
1593       x1 = 0;
1594       y1 = 0;
1595       x2 = rrb->base.Base.Width - 1;
1596       y2 = rrb->base.Base.Height - 1;
1597    }
1598 
1599    R200_SET_STATE(r200, sci, SCI_XY_1, x1 | (y1 << 16));
1600    R200_SET_STATE(r200, sci, SCI_XY_2, x2 | (y2 << 16));
1601 }
1602 
1603 
r200Viewport(struct gl_context * ctx)1604 static void r200Viewport(struct gl_context *ctx)
1605 {
1606    /* Don't pipeline viewport changes, conflict with window offset
1607     * setting below.  Could apply deltas to rescue pipelined viewport
1608     * values, or keep the originals hanging around.
1609     */
1610    r200UpdateWindow( ctx );
1611 
1612    radeon_viewport(ctx);
1613 }
1614 
r200DepthRange(struct gl_context * ctx)1615 static void r200DepthRange(struct gl_context *ctx)
1616 {
1617    r200UpdateWindow( ctx );
1618 }
1619 
1620 /* =============================================================
1621  * Miscellaneous
1622  */
1623 
r200RenderMode(struct gl_context * ctx,GLenum mode)1624 static void r200RenderMode( struct gl_context *ctx, GLenum mode )
1625 {
1626    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1627    FALLBACK( rmesa, R200_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1628 }
1629 
r200LogicOpCode(struct gl_context * ctx,enum gl_logicop_mode opcode)1630 static void r200LogicOpCode(struct gl_context *ctx, enum gl_logicop_mode opcode)
1631 {
1632    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1633 
1634    assert((unsigned) opcode <= 15);
1635 
1636    R200_STATECHANGE( rmesa, msk );
1637    rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = opcode;
1638 }
1639 
1640 /* =============================================================
1641  * State enable/disable
1642  */
1643 
r200Enable(struct gl_context * ctx,GLenum cap,GLboolean state)1644 static void r200Enable( struct gl_context *ctx, GLenum cap, GLboolean state )
1645 {
1646    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1647    GLuint p, flag;
1648 
1649    if ( R200_DEBUG & RADEON_STATE )
1650       fprintf( stderr, "%s( %s = %s )\n", __func__,
1651 	       _mesa_enum_to_string( cap ),
1652 	       state ? "GL_TRUE" : "GL_FALSE" );
1653 
1654    switch ( cap ) {
1655       /* Fast track this one...
1656        */
1657    case GL_TEXTURE_1D:
1658    case GL_TEXTURE_2D:
1659    case GL_TEXTURE_3D:
1660       break;
1661 
1662    case GL_ALPHA_TEST:
1663       R200_STATECHANGE( rmesa, ctx );
1664       if (state) {
1665 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ALPHA_TEST_ENABLE;
1666       } else {
1667 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ALPHA_TEST_ENABLE;
1668       }
1669       break;
1670 
1671    case GL_BLEND:
1672    case GL_COLOR_LOGIC_OP:
1673       r200_set_blend_state( ctx );
1674       break;
1675 
1676    case GL_CLIP_PLANE0:
1677    case GL_CLIP_PLANE1:
1678    case GL_CLIP_PLANE2:
1679    case GL_CLIP_PLANE3:
1680    case GL_CLIP_PLANE4:
1681    case GL_CLIP_PLANE5:
1682       p = cap-GL_CLIP_PLANE0;
1683       R200_STATECHANGE( rmesa, tcl );
1684       if (state) {
1685 	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0<<p);
1686 	 r200ClipPlane( ctx, cap, NULL );
1687       }
1688       else {
1689 	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0<<p);
1690       }
1691       break;
1692 
1693    case GL_COLOR_MATERIAL:
1694       r200ColorMaterial( ctx, 0, 0 );
1695       r200UpdateMaterial( ctx );
1696       break;
1697 
1698    case GL_CULL_FACE:
1699       r200CullFace( ctx, 0 );
1700       break;
1701 
1702    case GL_DEPTH_TEST:
1703       R200_STATECHANGE(rmesa, ctx );
1704       if ( state ) {
1705 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_Z_ENABLE;
1706       } else {
1707 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_Z_ENABLE;
1708       }
1709       break;
1710 
1711    case GL_DITHER:
1712       R200_STATECHANGE(rmesa, ctx );
1713       if ( state ) {
1714 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_DITHER_ENABLE;
1715 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1716       } else {
1717 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_DITHER_ENABLE;
1718 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  rmesa->radeon.state.color.roundEnable;
1719       }
1720       break;
1721 
1722    case GL_FOG:
1723       R200_STATECHANGE(rmesa, ctx );
1724       if ( state ) {
1725 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_FOG_ENABLE;
1726 	 r200Fogfv( ctx, GL_FOG_MODE, NULL );
1727       } else {
1728 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_FOG_ENABLE;
1729 	 R200_STATECHANGE(rmesa, tcl);
1730 	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK;
1731       }
1732       r200UpdateSpecular( ctx ); /* for PK_SPEC */
1733       if (rmesa->radeon.TclFallback)
1734 	 r200ChooseVertexState( ctx );
1735       _mesa_allow_light_in_model( ctx, !state );
1736       break;
1737 
1738    case GL_LIGHT0:
1739    case GL_LIGHT1:
1740    case GL_LIGHT2:
1741    case GL_LIGHT3:
1742    case GL_LIGHT4:
1743    case GL_LIGHT5:
1744    case GL_LIGHT6:
1745    case GL_LIGHT7:
1746       R200_STATECHANGE(rmesa, tcl);
1747       p = cap - GL_LIGHT0;
1748       if (p&1)
1749 	 flag = (R200_LIGHT_1_ENABLE |
1750 		 R200_LIGHT_1_ENABLE_AMBIENT |
1751 		 R200_LIGHT_1_ENABLE_SPECULAR);
1752       else
1753 	 flag = (R200_LIGHT_0_ENABLE |
1754 		 R200_LIGHT_0_ENABLE_AMBIENT |
1755 		 R200_LIGHT_0_ENABLE_SPECULAR);
1756 
1757       if (state)
1758 	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1759       else
1760 	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1761 
1762       /*
1763        */
1764       update_light_colors( ctx, p );
1765       break;
1766 
1767    case GL_LIGHTING:
1768       r200UpdateSpecular(ctx);
1769       /* for reflection map fixup - might set recheck_texgen for all units too */
1770       rmesa->radeon.NewGLState |= _NEW_TEXTURE;
1771       break;
1772 
1773    case GL_LINE_SMOOTH:
1774       R200_STATECHANGE( rmesa, ctx );
1775       if ( state ) {
1776 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  R200_ANTI_ALIAS_LINE;
1777       } else {
1778 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_LINE;
1779       }
1780       break;
1781 
1782    case GL_LINE_STIPPLE:
1783       R200_STATECHANGE( rmesa, set );
1784       if ( state ) {
1785 	 rmesa->hw.set.cmd[SET_RE_CNTL] |=  R200_PATTERN_ENABLE;
1786       } else {
1787 	 rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PATTERN_ENABLE;
1788       }
1789       break;
1790 
1791    case GL_NORMALIZE:
1792       R200_STATECHANGE( rmesa, tcl );
1793       if ( state ) {
1794 	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_NORMALIZE_NORMALS;
1795       } else {
1796 	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_NORMALIZE_NORMALS;
1797       }
1798       break;
1799 
1800       /* Pointsize registers on r200 only work for point sprites, and point smooth
1801        * doesn't work for point sprites (and isn't needed for 1.0 sized aa points).
1802        * In any case, setting pointmin == pointsizemax == 1.0 for aa points
1803        * is enough to satisfy conform.
1804        */
1805    case GL_POINT_SMOOTH:
1806       break;
1807 
1808       /* These don't really do anything, as we don't use the 3vtx
1809        * primitives yet.
1810        */
1811 #if 0
1812    case GL_POLYGON_OFFSET_POINT:
1813       R200_STATECHANGE( rmesa, set );
1814       if ( state ) {
1815 	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_POINT;
1816       } else {
1817 	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_POINT;
1818       }
1819       break;
1820 
1821    case GL_POLYGON_OFFSET_LINE:
1822       R200_STATECHANGE( rmesa, set );
1823       if ( state ) {
1824 	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_LINE;
1825       } else {
1826 	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_LINE;
1827       }
1828       break;
1829 #endif
1830 
1831    case GL_POINT_SPRITE_ARB:
1832       R200_STATECHANGE( rmesa, spr );
1833       if ( state ) {
1834 	 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_GEN_TEX_MASK &
1835             (ctx->Point.CoordReplace << R200_PS_GEN_TEX_0_SHIFT);
1836       } else {
1837 	 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~R200_PS_GEN_TEX_MASK;
1838       }
1839       break;
1840 
1841    case GL_POLYGON_OFFSET_FILL:
1842       R200_STATECHANGE( rmesa, set );
1843       if ( state ) {
1844 	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_TRI;
1845       } else {
1846 	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_TRI;
1847       }
1848       break;
1849 
1850    case GL_POLYGON_SMOOTH:
1851       R200_STATECHANGE( rmesa, ctx );
1852       if ( state ) {
1853 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  R200_ANTI_ALIAS_POLY;
1854       } else {
1855 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_POLY;
1856       }
1857       break;
1858 
1859    case GL_POLYGON_STIPPLE:
1860       R200_STATECHANGE(rmesa, set );
1861       if ( state ) {
1862 	 rmesa->hw.set.cmd[SET_RE_CNTL] |=  R200_STIPPLE_ENABLE;
1863       } else {
1864 	 rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_STIPPLE_ENABLE;
1865       }
1866       break;
1867 
1868    case GL_RESCALE_NORMAL_EXT: {
1869       GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1870       R200_STATECHANGE( rmesa, tcl );
1871       if ( tmp ) {
1872 	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_RESCALE_NORMALS;
1873       } else {
1874 	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
1875       }
1876       break;
1877    }
1878 
1879    case GL_SCISSOR_TEST:
1880       radeon_firevertices(&rmesa->radeon);
1881       rmesa->radeon.state.scissor.enabled = state;
1882       radeonUpdateScissor( ctx );
1883       break;
1884 
1885    case GL_STENCIL_TEST:
1886       {
1887 	 GLboolean hw_stencil = GL_FALSE;
1888 	 if (ctx->DrawBuffer) {
1889 	    struct radeon_renderbuffer *rrbStencil
1890 	       = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1891 	    hw_stencil = (rrbStencil && rrbStencil->bo);
1892 	 }
1893 
1894 	 if (hw_stencil) {
1895 	    R200_STATECHANGE( rmesa, ctx );
1896 	    if ( state ) {
1897 	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_STENCIL_ENABLE;
1898 	    } else {
1899 	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE;
1900 	    }
1901 	 } else {
1902 	    FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );
1903 	 }
1904       }
1905       break;
1906 
1907    case GL_TEXTURE_GEN_Q:
1908    case GL_TEXTURE_GEN_R:
1909    case GL_TEXTURE_GEN_S:
1910    case GL_TEXTURE_GEN_T:
1911       /* Picked up in r200UpdateTextureState.
1912        */
1913       rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1914       break;
1915 
1916    case GL_COLOR_SUM_EXT:
1917       r200UpdateSpecular ( ctx );
1918       break;
1919 
1920    case GL_VERTEX_PROGRAM_ARB:
1921       if (!state) {
1922 	 GLuint i;
1923 	 rmesa->curr_vp_hw = NULL;
1924 	 R200_STATECHANGE( rmesa, vap );
1925 	 rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_PROG_VTX_SHADER_ENABLE;
1926 	 /* mark all tcl atoms (tcl vector state got overwritten) dirty
1927 	    not sure about tcl scalar state - we need at least grd
1928 	    with vert progs too.
1929 	    ucp looks like it doesn't get overwritten (may even work
1930 	    with vp for pos-invariant progs if we're lucky) */
1931 	 R200_STATECHANGE( rmesa, mtl[0] );
1932 	 R200_STATECHANGE( rmesa, mtl[1] );
1933 	 R200_STATECHANGE( rmesa, fog );
1934 	 R200_STATECHANGE( rmesa, glt );
1935 	 R200_STATECHANGE( rmesa, eye );
1936 	 for (i = R200_MTX_MV; i <= R200_MTX_TEX5; i++) {
1937 	    R200_STATECHANGE( rmesa, mat[i] );
1938 	 }
1939 	 for (i = 0 ; i < 8; i++) {
1940 	    R200_STATECHANGE( rmesa, lit[i] );
1941 	 }
1942 	 R200_STATECHANGE( rmesa, tcl );
1943 	 for (i = 0; i <= ctx->Const.MaxClipPlanes; i++) {
1944 	    if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
1945 	       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0 << i);
1946 	    }
1947 /*	    else {
1948 	       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0 << i);
1949 	    }*/
1950 	 }
1951 	 /* ugly. Need to call everything which might change compsel. */
1952 	 r200UpdateSpecular( ctx );
1953 #if 0
1954 	/* shouldn't be necessary, as it's picked up anyway in r200ValidateState (_NEW_PROGRAM),
1955 	   but without it doom3 locks up at always the same places. Why? */
1956 	/* FIXME: This can (and should) be replaced by a call to the TCL_STATE_FLUSH reg before
1957 	   accessing VAP_SE_VAP_CNTL. Requires drm changes (done). Remove after some time... */
1958 	 r200UpdateTextureState( ctx );
1959 	 /* if we call r200UpdateTextureState we need the code below because we are calling it with
1960 	    non-current derived enabled values which may revert the state atoms for frag progs even when
1961 	    they already got disabled... ugh
1962 	    Should really figure out why we need to call r200UpdateTextureState in the first place */
1963 	 GLuint unit;
1964 	 for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
1965 	    R200_STATECHANGE( rmesa, pix[unit] );
1966 	    R200_STATECHANGE( rmesa, tex[unit] );
1967 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
1968 		~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
1969 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
1970 	    /* need to guard this with drmSupportsFragmentShader? Should never get here if
1971 	       we don't announce ATI_fs, right? */
1972 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
1973          }
1974 	 R200_STATECHANGE( rmesa, cst );
1975 	 R200_STATECHANGE( rmesa, tf );
1976 	 rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
1977 #endif
1978       }
1979       else {
1980 	 /* picked up later */
1981       }
1982       /* call functions which change hw state based on ARB_vp enabled or not. */
1983       r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
1984       r200Fogfv( ctx, GL_FOG_COORD_SRC, NULL );
1985       break;
1986 
1987    case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
1988       r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
1989       break;
1990 
1991    case GL_FRAGMENT_SHADER_ATI:
1992       if ( !state ) {
1993 	 /* restore normal tex env colors and make sure tex env combine will get updated
1994 	    mark env atoms dirty (as their data was overwritten by afs even
1995 	    if they didn't change) and restore tex coord routing */
1996 	 GLuint unit;
1997 	 for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
1998 	    R200_STATECHANGE( rmesa, pix[unit] );
1999 	    R200_STATECHANGE( rmesa, tex[unit] );
2000 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
2001 		~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
2002 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
2003 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
2004          }
2005 	 R200_STATECHANGE( rmesa, cst );
2006 	 R200_STATECHANGE( rmesa, tf );
2007 	 rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
2008       }
2009       else {
2010 	 /* need to mark this dirty as pix/tf atoms have overwritten the data
2011 	    even if the data in the atoms didn't change */
2012 	 R200_STATECHANGE( rmesa, atf );
2013 	 R200_STATECHANGE( rmesa, afs[1] );
2014 	 /* everything else picked up in r200UpdateTextureState hopefully */
2015       }
2016       break;
2017    default:
2018       return;
2019    }
2020 }
2021 
2022 
r200LightingSpaceChange(struct gl_context * ctx)2023 void r200LightingSpaceChange( struct gl_context *ctx )
2024 {
2025    r200ContextPtr rmesa = R200_CONTEXT(ctx);
2026    GLboolean tmp;
2027 
2028    if (R200_DEBUG & RADEON_STATE)
2029       fprintf(stderr, "%s %d BEFORE %x\n", __func__, ctx->_NeedEyeCoords,
2030 	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
2031 
2032    if (ctx->_NeedEyeCoords)
2033       tmp = ctx->Transform.RescaleNormals;
2034    else
2035       tmp = !ctx->Transform.RescaleNormals;
2036 
2037    R200_STATECHANGE( rmesa, tcl );
2038    if ( tmp ) {
2039       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_RESCALE_NORMALS;
2040    } else {
2041       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
2042    }
2043 
2044    if (R200_DEBUG & RADEON_STATE)
2045       fprintf(stderr, "%s %d AFTER %x\n", __func__, ctx->_NeedEyeCoords,
2046 	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
2047 }
2048 
2049 /* =============================================================
2050  * Deferred state management - matrices, textures, other?
2051  */
2052 
2053 
2054 
2055 
upload_matrix(r200ContextPtr rmesa,GLfloat * src,int idx)2056 static void upload_matrix( r200ContextPtr rmesa, GLfloat *src, int idx )
2057 {
2058    float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
2059    int i;
2060 
2061 
2062    for (i = 0 ; i < 4 ; i++) {
2063       *dest++ = src[i];
2064       *dest++ = src[i+4];
2065       *dest++ = src[i+8];
2066       *dest++ = src[i+12];
2067    }
2068 
2069    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2070 }
2071 
upload_matrix_t(r200ContextPtr rmesa,const GLfloat * src,int idx)2072 static void upload_matrix_t( r200ContextPtr rmesa, const GLfloat *src, int idx )
2073 {
2074    float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
2075    memcpy(dest, src, 16*sizeof(float));
2076    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2077 }
2078 
2079 
update_texturematrix(struct gl_context * ctx)2080 static void update_texturematrix( struct gl_context *ctx )
2081 {
2082    r200ContextPtr rmesa = R200_CONTEXT( ctx );
2083    GLuint tpc = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0];
2084    GLuint compsel = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL];
2085    int unit;
2086 
2087    if (R200_DEBUG & RADEON_STATE)
2088       fprintf(stderr, "%s before COMPSEL: %x\n", __func__,
2089 	      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]);
2090 
2091    rmesa->TexMatEnabled = 0;
2092    rmesa->TexMatCompSel = 0;
2093 
2094    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
2095       if (!ctx->Texture.Unit[unit]._Current)
2096 	 continue;
2097 
2098       if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2099 	 rmesa->TexMatEnabled |= (R200_TEXGEN_TEXMAT_0_ENABLE|
2100 				  R200_TEXMAT_0_ENABLE) << unit;
2101 
2102 	 rmesa->TexMatCompSel |= R200_OUTPUT_TEX_0 << unit;
2103 
2104 	 if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
2105 	    /* Need to preconcatenate any active texgen
2106 	     * obj/eyeplane matrices:
2107 	     */
2108 	    _math_matrix_mul_matrix( &rmesa->tmpmat,
2109 				     ctx->TextureMatrixStack[unit].Top,
2110 				     &rmesa->TexGenMatrix[unit] );
2111 	    upload_matrix( rmesa, rmesa->tmpmat.m, R200_MTX_TEX0+unit );
2112 	 }
2113 	 else {
2114 	    upload_matrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,
2115 			   R200_MTX_TEX0+unit );
2116 	 }
2117       }
2118       else if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
2119 	 upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m,
2120 			R200_MTX_TEX0+unit );
2121       }
2122    }
2123 
2124    tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
2125    if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0]) {
2126       R200_STATECHANGE(rmesa, tcg);
2127       rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = tpc;
2128    }
2129 
2130    compsel &= ~R200_OUTPUT_TEX_MASK;
2131    compsel |= rmesa->TexMatCompSel | rmesa->TexGenCompSel;
2132    if (compsel != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]) {
2133       R200_STATECHANGE(rmesa, vtx);
2134       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = compsel;
2135    }
2136 }
2137 
r200ValidateBuffers(struct gl_context * ctx)2138 GLboolean r200ValidateBuffers(struct gl_context *ctx)
2139 {
2140    r200ContextPtr rmesa = R200_CONTEXT(ctx);
2141    struct radeon_renderbuffer *rrb;
2142    struct radeon_dma_bo *dma_bo;
2143    int i, ret;
2144 
2145 	if (RADEON_DEBUG & RADEON_IOCTL)
2146 		fprintf(stderr, "%s\n", __func__);
2147    radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2148 
2149    rrb = radeon_get_colorbuffer(&rmesa->radeon);
2150    /* color buffer */
2151    if (rrb && rrb->bo) {
2152      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2153 				       0, RADEON_GEM_DOMAIN_VRAM);
2154    }
2155 
2156    /* depth buffer */
2157    rrb = radeon_get_depthbuffer(&rmesa->radeon);
2158    /* color buffer */
2159    if (rrb && rrb->bo) {
2160      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2161 				       0, RADEON_GEM_DOMAIN_VRAM);
2162    }
2163 
2164    for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; ++i) {
2165       radeonTexObj *t;
2166 
2167       if (!ctx->Texture.Unit[i]._Current)
2168 	 continue;
2169 
2170       t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
2171       if (t->image_override && t->bo)
2172 	radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2173 			   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2174       else if (t->mt->bo)
2175 	radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2176 			   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2177    }
2178 
2179    dma_bo = first_elem(&rmesa->radeon.dma.reserved);
2180    {
2181        ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, dma_bo->bo, RADEON_GEM_DOMAIN_GTT, 0);
2182        if (ret)
2183 	   return GL_FALSE;
2184    }
2185    return GL_TRUE;
2186 }
2187 
r200ValidateState(struct gl_context * ctx)2188 GLboolean r200ValidateState( struct gl_context *ctx )
2189 {
2190    r200ContextPtr rmesa = R200_CONTEXT(ctx);
2191    GLuint new_state = rmesa->radeon.NewGLState;
2192 
2193    if (new_state & _NEW_BUFFERS) {
2194       _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
2195       /* this updates the DrawBuffer's Width/Height if it's a FBO */
2196       _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
2197 
2198       R200_STATECHANGE(rmesa, ctx);
2199    }
2200 
2201    if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)) {
2202       r200UpdateTextureState( ctx );
2203       new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2204       r200UpdateLocalViewer( ctx );
2205    }
2206 
2207    /* we need to do a space check here */
2208    if (!r200ValidateBuffers(ctx))
2209      return GL_FALSE;
2210 
2211 /* FIXME: don't really need most of these when vertex progs are enabled */
2212 
2213    /* Need an event driven matrix update?
2214     */
2215    if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2216       upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, R200_MTX_MVP );
2217 
2218    /* Need these for lighting (shouldn't upload otherwise)
2219     */
2220    if (new_state & (_NEW_MODELVIEW)) {
2221       upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, R200_MTX_MV );
2222       upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, R200_MTX_IMV );
2223    }
2224 
2225    /* Does this need to be triggered on eg. modelview for
2226     * texgen-derived objplane/eyeplane matrices?
2227     */
2228    if (new_state & (_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) {
2229       update_texturematrix( ctx );
2230    }
2231 
2232    if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2233       update_light( ctx );
2234    }
2235 
2236    /* emit all active clip planes if projection matrix changes.
2237     */
2238    if (new_state & (_NEW_PROJECTION)) {
2239       if (ctx->Transform.ClipPlanesEnabled)
2240 	 r200UpdateClipPlanes( ctx );
2241    }
2242 
2243    if (new_state & (_NEW_PROGRAM|
2244                     _NEW_PROGRAM_CONSTANTS |
2245    /* need to test for pretty much anything due to possible parameter bindings */
2246 	_NEW_MODELVIEW|_NEW_PROJECTION|_NEW_TRANSFORM|
2247 	_NEW_LIGHT|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX|
2248 	_NEW_FOG|_NEW_POINT|_NEW_TRACK_MATRIX)) {
2249       if (_mesa_arb_vertex_program_enabled(ctx)) {
2250 	 r200SetupVertexProg( ctx );
2251       }
2252       else TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, 0);
2253    }
2254 
2255    rmesa->radeon.NewGLState = 0;
2256    return GL_TRUE;
2257 }
2258 
2259 
r200InvalidateState(struct gl_context * ctx)2260 static void r200InvalidateState(struct gl_context *ctx)
2261 {
2262    GLuint new_state = ctx->NewState;
2263 
2264    r200ContextPtr rmesa = R200_CONTEXT(ctx);
2265 
2266    if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
2267       _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
2268 
2269    _swrast_InvalidateState( ctx, new_state );
2270    _swsetup_InvalidateState( ctx, new_state );
2271    _tnl_InvalidateState( ctx, new_state );
2272    R200_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2273 
2274    if (new_state & _NEW_PROGRAM)
2275       rmesa->curr_vp_hw = NULL;
2276 }
2277 
2278 /* A hack.  The r200 can actually cope just fine with materials
2279  * between begin/ends, so fix this.
2280  * Should map to inputs just like the generic vertex arrays for vertex progs.
2281  * In theory there could still be too many and we'd still need a fallback.
2282  */
check_material(struct gl_context * ctx)2283 static GLboolean check_material( struct gl_context *ctx )
2284 {
2285    TNLcontext *tnl = TNL_CONTEXT(ctx);
2286    GLint i;
2287 
2288    for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2289 	i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2290 	i++)
2291       if (tnl->vb.AttribPtr[i] &&
2292 	  tnl->vb.AttribPtr[i]->stride)
2293 	 return GL_TRUE;
2294 
2295    return GL_FALSE;
2296 }
2297 
r200WrapRunPipeline(struct gl_context * ctx)2298 static void r200WrapRunPipeline( struct gl_context *ctx )
2299 {
2300    r200ContextPtr rmesa = R200_CONTEXT(ctx);
2301    GLboolean has_material;
2302 
2303    if (0)
2304       fprintf(stderr, "%s, newstate: %x\n", __func__, rmesa->radeon.NewGLState);
2305 
2306    /* Validate state:
2307     */
2308    if (rmesa->radeon.NewGLState)
2309       if (!r200ValidateState( ctx ))
2310 	 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2311 
2312    has_material = !_mesa_arb_vertex_program_enabled(ctx) &&
2313                   ctx->Light.Enabled && check_material( ctx );
2314 
2315    if (has_material) {
2316       TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE );
2317    }
2318 
2319    /* Run the pipeline.
2320     */
2321    _tnl_run_pipeline( ctx );
2322 
2323    if (has_material) {
2324       TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_FALSE );
2325    }
2326 }
2327 
2328 
r200PolygonStipple(struct gl_context * ctx,const GLubyte * mask)2329 static void r200PolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2330 {
2331    r200ContextPtr r200 = R200_CONTEXT(ctx);
2332    GLint i;
2333 
2334    radeon_firevertices(&r200->radeon);
2335 
2336    radeon_print(RADEON_STATE, RADEON_TRACE,
2337 		   "%s(%p) first 32 bits are %x.\n",
2338 		   __func__,
2339 		   ctx,
2340 		   *(uint32_t*)mask);
2341 
2342    R200_STATECHANGE(r200, stp);
2343 
2344    /* Must flip pattern upside down.
2345     */
2346    for ( i = 31 ; i >= 0; i--) {
2347      r200->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2348    }
2349 }
2350 /* Initialize the driver's state functions.
2351  */
r200InitStateFuncs(radeonContextPtr radeon,struct dd_function_table * functions)2352 void r200InitStateFuncs( radeonContextPtr radeon, struct dd_function_table *functions )
2353 {
2354    functions->UpdateState		= r200InvalidateState;
2355    functions->LightingSpaceChange	= r200LightingSpaceChange;
2356 
2357    functions->DrawBuffer		= radeonDrawBuffer;
2358    functions->ReadBuffer		= radeonReadBuffer;
2359 
2360    functions->CopyPixels                = _mesa_meta_CopyPixels;
2361    functions->DrawPixels                = _mesa_meta_DrawPixels;
2362    functions->ReadPixels                = radeonReadPixels;
2363 
2364    functions->AlphaFunc			= r200AlphaFunc;
2365    functions->BlendColor		= r200BlendColor;
2366    functions->BlendEquationSeparate	= r200BlendEquationSeparate;
2367    functions->BlendFuncSeparate		= r200BlendFuncSeparate;
2368    functions->ClipPlane			= r200ClipPlane;
2369    functions->ColorMask			= r200ColorMask;
2370    functions->CullFace			= r200CullFace;
2371    functions->DepthFunc			= r200DepthFunc;
2372    functions->DepthMask			= r200DepthMask;
2373    functions->DepthRange		= r200DepthRange;
2374    functions->Enable			= r200Enable;
2375    functions->Fogfv			= r200Fogfv;
2376    functions->FrontFace			= r200FrontFace;
2377    functions->LightModelfv		= r200LightModelfv;
2378    functions->Lightfv			= r200Lightfv;
2379    functions->LineStipple		= r200LineStipple;
2380    functions->LineWidth			= r200LineWidth;
2381    functions->LogicOpcode		= r200LogicOpCode;
2382    functions->PolygonMode		= r200PolygonMode;
2383    functions->PolygonOffset		= r200PolygonOffset;
2384    functions->PolygonStipple		= r200PolygonStipple;
2385    functions->PointParameterfv		= r200PointParameter;
2386    functions->PointSize			= r200PointSize;
2387    functions->RenderMode		= r200RenderMode;
2388    functions->Scissor			= radeonScissor;
2389    functions->ShadeModel		= r200ShadeModel;
2390    functions->StencilFuncSeparate	= r200StencilFuncSeparate;
2391    functions->StencilMaskSeparate	= r200StencilMaskSeparate;
2392    functions->StencilOpSeparate		= r200StencilOpSeparate;
2393    functions->Viewport			= r200Viewport;
2394 }
2395 
2396 
r200InitTnlFuncs(struct gl_context * ctx)2397 void r200InitTnlFuncs( struct gl_context *ctx )
2398 {
2399    TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = r200UpdateMaterial;
2400    TNL_CONTEXT(ctx)->Driver.RunPipeline = r200WrapRunPipeline;
2401 }
2402