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