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