Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / radeon / radeon_state.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30  * Authors:
31  *   Gareth Hughes <gareth@valinux.com>
32  *   Keith Whitwell <keith@tungstengraphics.com>
33  */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/simple_list.h"
43 #include "main/state.h"
44
45 #include "vbo/vbo.h"
46 #include "tnl/tnl.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "drivers/common/meta.h"
50
51 #include "radeon_context.h"
52 #include "radeon_mipmap_tree.h"
53 #include "radeon_ioctl.h"
54 #include "radeon_state.h"
55 #include "radeon_tcl.h"
56 #include "radeon_tex.h"
57 #include "radeon_swtcl.h"
58
59 static void radeonUpdateSpecular( struct gl_context *ctx );
60
61 /* =============================================================
62  * Alpha blending
63  */
64
65 static void radeonAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
66 {
67    r100ContextPtr rmesa = R100_CONTEXT(ctx);
68    int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC];
69    GLubyte refByte;
70
71    CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
72
73    RADEON_STATECHANGE( rmesa, ctx );
74
75    pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK);
76    pp_misc |= (refByte & RADEON_REF_ALPHA_MASK);
77
78    switch ( func ) {
79    case GL_NEVER:
80       pp_misc |= RADEON_ALPHA_TEST_FAIL;
81       break;
82    case GL_LESS:
83       pp_misc |= RADEON_ALPHA_TEST_LESS;
84       break;
85    case GL_EQUAL:
86       pp_misc |= RADEON_ALPHA_TEST_EQUAL;
87       break;
88    case GL_LEQUAL:
89       pp_misc |= RADEON_ALPHA_TEST_LEQUAL;
90       break;
91    case GL_GREATER:
92       pp_misc |= RADEON_ALPHA_TEST_GREATER;
93       break;
94    case GL_NOTEQUAL:
95       pp_misc |= RADEON_ALPHA_TEST_NEQUAL;
96       break;
97    case GL_GEQUAL:
98       pp_misc |= RADEON_ALPHA_TEST_GEQUAL;
99       break;
100    case GL_ALWAYS:
101       pp_misc |= RADEON_ALPHA_TEST_PASS;
102       break;
103    }
104
105    rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
106 }
107
108 static void radeonBlendEquationSeparate( struct gl_context *ctx,
109                                          GLenum modeRGB, GLenum modeA )
110 {
111    r100ContextPtr rmesa = R100_CONTEXT(ctx);
112    GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK;
113    GLboolean fallback = GL_FALSE;
114
115    assert( modeRGB == modeA );
116
117    switch ( modeRGB ) {
118    case GL_FUNC_ADD:
119    case GL_LOGIC_OP:
120       b |= RADEON_COMB_FCN_ADD_CLAMP;
121       break;
122
123    case GL_FUNC_SUBTRACT:
124       b |= RADEON_COMB_FCN_SUB_CLAMP;
125       break;
126
127    default:
128       if (ctx->Color.BlendEnabled)
129          fallback = GL_TRUE;
130       else
131          b |= RADEON_COMB_FCN_ADD_CLAMP;
132       break;
133    }
134
135    FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, fallback );
136    if ( !fallback ) {
137       RADEON_STATECHANGE( rmesa, ctx );
138       rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
139       if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
140             && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
141          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
142       } else {
143          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
144       }
145    }
146 }
147
148 static void radeonBlendFuncSeparate( struct gl_context *ctx,
149                                      GLenum sfactorRGB, GLenum dfactorRGB,
150                                      GLenum sfactorA, GLenum dfactorA )
151 {
152    r100ContextPtr rmesa = R100_CONTEXT(ctx);
153    GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] &
154       ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
155    GLboolean fallback = GL_FALSE;
156
157    switch ( ctx->Color.Blend[0].SrcRGB ) {
158    case GL_ZERO:
159       b |= RADEON_SRC_BLEND_GL_ZERO;
160       break;
161    case GL_ONE:
162       b |= RADEON_SRC_BLEND_GL_ONE;
163       break;
164    case GL_DST_COLOR:
165       b |= RADEON_SRC_BLEND_GL_DST_COLOR;
166       break;
167    case GL_ONE_MINUS_DST_COLOR:
168       b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
169       break;
170    case GL_SRC_COLOR:
171       b |= RADEON_SRC_BLEND_GL_SRC_COLOR;
172       break;
173    case GL_ONE_MINUS_SRC_COLOR:
174       b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR;
175       break;
176    case GL_SRC_ALPHA:
177       b |= RADEON_SRC_BLEND_GL_SRC_ALPHA;
178       break;
179    case GL_ONE_MINUS_SRC_ALPHA:
180       b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
181       break;
182    case GL_DST_ALPHA:
183       b |= RADEON_SRC_BLEND_GL_DST_ALPHA;
184       break;
185    case GL_ONE_MINUS_DST_ALPHA:
186       b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
187       break;
188    case GL_SRC_ALPHA_SATURATE:
189       b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
190       break;
191    case GL_CONSTANT_COLOR:
192    case GL_ONE_MINUS_CONSTANT_COLOR:
193    case GL_CONSTANT_ALPHA:
194    case GL_ONE_MINUS_CONSTANT_ALPHA:
195       if (ctx->Color.BlendEnabled)
196          fallback = GL_TRUE;
197       else
198          b |= RADEON_SRC_BLEND_GL_ONE;
199       break;
200    default:
201       break;
202    }
203
204    switch ( ctx->Color.Blend[0].DstRGB ) {
205    case GL_ZERO:
206       b |= RADEON_DST_BLEND_GL_ZERO;
207       break;
208    case GL_ONE:
209       b |= RADEON_DST_BLEND_GL_ONE;
210       break;
211    case GL_SRC_COLOR:
212       b |= RADEON_DST_BLEND_GL_SRC_COLOR;
213       break;
214    case GL_ONE_MINUS_SRC_COLOR:
215       b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR;
216       break;
217    case GL_SRC_ALPHA:
218       b |= RADEON_DST_BLEND_GL_SRC_ALPHA;
219       break;
220    case GL_ONE_MINUS_SRC_ALPHA:
221       b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
222       break;
223    case GL_DST_COLOR:
224       b |= RADEON_DST_BLEND_GL_DST_COLOR;
225       break;
226    case GL_ONE_MINUS_DST_COLOR:
227       b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR;
228       break;
229    case GL_DST_ALPHA:
230       b |= RADEON_DST_BLEND_GL_DST_ALPHA;
231       break;
232    case GL_ONE_MINUS_DST_ALPHA:
233       b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA;
234       break;
235    case GL_CONSTANT_COLOR:
236    case GL_ONE_MINUS_CONSTANT_COLOR:
237    case GL_CONSTANT_ALPHA:
238    case GL_ONE_MINUS_CONSTANT_ALPHA:
239       if (ctx->Color.BlendEnabled)
240          fallback = GL_TRUE;
241       else
242          b |= RADEON_DST_BLEND_GL_ZERO;
243       break;
244    default:
245       break;
246    }
247
248    FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback );
249    if ( !fallback ) {
250       RADEON_STATECHANGE( rmesa, ctx );
251       rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
252    }
253 }
254
255
256 /* =============================================================
257  * Depth testing
258  */
259
260 static void radeonDepthFunc( struct gl_context *ctx, GLenum func )
261 {
262    r100ContextPtr rmesa = R100_CONTEXT(ctx);
263
264    RADEON_STATECHANGE( rmesa, ctx );
265    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK;
266
267    switch ( ctx->Depth.Func ) {
268    case GL_NEVER:
269       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEVER;
270       break;
271    case GL_LESS:
272       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LESS;
273       break;
274    case GL_EQUAL:
275       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_EQUAL;
276       break;
277    case GL_LEQUAL:
278       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LEQUAL;
279       break;
280    case GL_GREATER:
281       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GREATER;
282       break;
283    case GL_NOTEQUAL:
284       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEQUAL;
285       break;
286    case GL_GEQUAL:
287       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GEQUAL;
288       break;
289    case GL_ALWAYS:
290       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_ALWAYS;
291       break;
292    }
293 }
294
295
296 static void radeonDepthMask( struct gl_context *ctx, GLboolean flag )
297 {
298    r100ContextPtr rmesa = R100_CONTEXT(ctx);
299    RADEON_STATECHANGE( rmesa, ctx );
300
301    if ( ctx->Depth.Mask ) {
302       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |=  RADEON_Z_WRITE_ENABLE;
303    } else {
304       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_WRITE_ENABLE;
305    }
306 }
307
308 static void radeonClearDepth( struct gl_context *ctx, GLclampd d )
309 {
310    r100ContextPtr rmesa = R100_CONTEXT(ctx);
311    GLuint format = (rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &
312                     RADEON_DEPTH_FORMAT_MASK);
313
314    switch ( format ) {
315    case RADEON_DEPTH_FORMAT_16BIT_INT_Z:
316       rmesa->radeon.state.depth.clear = d * 0x0000ffff;
317       break;
318    case RADEON_DEPTH_FORMAT_24BIT_INT_Z:
319       rmesa->radeon.state.depth.clear = d * 0x00ffffff;
320       break;
321    }
322 }
323
324
325 /* =============================================================
326  * Fog
327  */
328
329
330 static void radeonFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
331 {
332    r100ContextPtr rmesa = R100_CONTEXT(ctx);
333    union { int i; float f; } c, d;
334    GLchan col[4];
335
336    switch (pname) {
337    case GL_FOG_MODE:
338       if (!ctx->Fog.Enabled)
339          return;
340       RADEON_STATECHANGE(rmesa, tcl);
341       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
342       switch (ctx->Fog.Mode) {
343       case GL_LINEAR:
344          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
345          break;
346       case GL_EXP:
347          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
348          break;
349       case GL_EXP2:
350          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
351          break;
352       default:
353          return;
354       }
355    /* fallthrough */
356    case GL_FOG_DENSITY:
357    case GL_FOG_START:
358    case GL_FOG_END:
359       if (!ctx->Fog.Enabled)
360          return;
361       c.i = rmesa->hw.fog.cmd[FOG_C];
362       d.i = rmesa->hw.fog.cmd[FOG_D];
363       switch (ctx->Fog.Mode) {
364       case GL_EXP:
365          c.f = 0.0;
366          /* While this is the opposite sign from the DDK, it makes the fog test
367           * pass, and matches r200.
368           */
369          d.f = -ctx->Fog.Density;
370          break;
371       case GL_EXP2:
372          c.f = 0.0;
373          d.f = -(ctx->Fog.Density * ctx->Fog.Density);
374          break;
375       case GL_LINEAR:
376          if (ctx->Fog.Start == ctx->Fog.End) {
377             c.f = 1.0F;
378             d.f = 1.0F;
379          } else {
380             c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
381             /* While this is the opposite sign from the DDK, it makes the fog
382              * test pass, and matches r200.
383              */
384             d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
385          }
386          break;
387       default:
388          break;
389       }
390       if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
391          RADEON_STATECHANGE( rmesa, fog );
392          rmesa->hw.fog.cmd[FOG_C] = c.i;
393          rmesa->hw.fog.cmd[FOG_D] = d.i;
394       }
395       break;
396    case GL_FOG_COLOR:
397       RADEON_STATECHANGE( rmesa, ctx );
398       UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
399       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
400       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
401          radeonPackColor( 4, col[0], col[1], col[2], 0 );
402       break;
403    case GL_FOG_COORD_SRC:
404       radeonUpdateSpecular( ctx );
405       break;
406    default:
407       return;
408    }
409 }
410
411 /* =============================================================
412  * Culling
413  */
414
415 static void radeonCullFace( struct gl_context *ctx, GLenum unused )
416 {
417    r100ContextPtr rmesa = R100_CONTEXT(ctx);
418    GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
419    GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
420
421    s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;
422    t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK);
423
424    if ( ctx->Polygon.CullFlag ) {
425       switch ( ctx->Polygon.CullFaceMode ) {
426       case GL_FRONT:
427          s &= ~RADEON_FFACE_SOLID;
428          t |= RADEON_CULL_FRONT;
429          break;
430       case GL_BACK:
431          s &= ~RADEON_BFACE_SOLID;
432          t |= RADEON_CULL_BACK;
433          break;
434       case GL_FRONT_AND_BACK:
435          s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);
436          t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK);
437          break;
438       }
439    }
440
441    if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
442       RADEON_STATECHANGE(rmesa, set );
443       rmesa->hw.set.cmd[SET_SE_CNTL] = s;
444    }
445
446    if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
447       RADEON_STATECHANGE(rmesa, tcl );
448       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
449    }
450 }
451
452 static void radeonFrontFace( struct gl_context *ctx, GLenum mode )
453 {
454    r100ContextPtr rmesa = R100_CONTEXT(ctx);
455
456    RADEON_STATECHANGE( rmesa, set );
457    rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK;
458
459    RADEON_STATECHANGE( rmesa, tcl );
460    rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;
461
462    /* Winding is inverted when rendering to FBO */
463    if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
464       mode = (mode == GL_CW) ? GL_CCW : GL_CW;
465
466    switch ( mode ) {
467    case GL_CW:
468       rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW;
469       break;
470    case GL_CCW:
471       rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CCW;
472       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW;
473       break;
474    }
475 }
476
477
478 /* =============================================================
479  * Line state
480  */
481 static void radeonLineWidth( struct gl_context *ctx, GLfloat widthf )
482 {
483    r100ContextPtr rmesa = R100_CONTEXT(ctx);
484
485    RADEON_STATECHANGE( rmesa, lin );
486    RADEON_STATECHANGE( rmesa, set );
487
488    /* Line width is stored in U6.4 format.
489     */
490    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0);
491    if ( widthf > 1.0 ) {
492       rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_WIDELINE_ENABLE;
493    } else {
494       rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE;
495    }
496 }
497
498 static void radeonLineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
499 {
500    r100ContextPtr rmesa = R100_CONTEXT(ctx);
501
502    RADEON_STATECHANGE( rmesa, lin );
503    rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
504       ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
505 }
506
507
508 /* =============================================================
509  * Masks
510  */
511 static void radeonColorMask( struct gl_context *ctx,
512                              GLboolean r, GLboolean g,
513                              GLboolean b, GLboolean a )
514 {
515    r100ContextPtr rmesa = R100_CONTEXT(ctx);
516    struct radeon_renderbuffer *rrb;
517    GLuint mask;
518
519    rrb = radeon_get_colorbuffer(&rmesa->radeon);
520    if (!rrb)
521      return;
522
523    mask = radeonPackColor( rrb->cpp,
524                            ctx->Color.ColorMask[0][RCOMP],
525                            ctx->Color.ColorMask[0][GCOMP],
526                            ctx->Color.ColorMask[0][BCOMP],
527                            ctx->Color.ColorMask[0][ACOMP] );
528
529    if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
530       RADEON_STATECHANGE( rmesa, msk );
531       rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
532    }
533 }
534
535
536 /* =============================================================
537  * Polygon state
538  */
539
540 static void radeonPolygonOffset( struct gl_context *ctx,
541                                  GLfloat factor, GLfloat units )
542 {
543    r100ContextPtr rmesa = R100_CONTEXT(ctx);
544    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
545    float_ui32_type constant =  { units * depthScale };
546    float_ui32_type factoru = { factor };
547
548    RADEON_STATECHANGE( rmesa, zbs );
549    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR]   = factoru.ui32;
550    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
551 }
552
553 static void radeonPolygonStipplePreKMS( struct gl_context *ctx, const GLubyte *mask )
554 {
555    r100ContextPtr rmesa = R100_CONTEXT(ctx);
556    GLuint i;
557    drm_radeon_stipple_t stipple;
558
559    /* Must flip pattern upside down.
560     */
561    for ( i = 0 ; i < 32 ; i++ ) {
562       rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i];
563    }
564
565    /* TODO: push this into cmd mechanism
566     */
567    radeon_firevertices(&rmesa->radeon);
568    LOCK_HARDWARE( &rmesa->radeon );
569
570    /* FIXME: Use window x,y offsets into stipple RAM.
571     */
572    stipple.mask = rmesa->state.stipple.mask;
573    drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE,
574                     &stipple, sizeof(drm_radeon_stipple_t) );
575    UNLOCK_HARDWARE( &rmesa->radeon );
576 }
577
578 static void radeonPolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
579 {
580    r100ContextPtr rmesa = R100_CONTEXT(ctx);
581    GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
582
583    /* Can't generally do unfilled via tcl, but some good special
584     * cases work.
585     */
586    TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag);
587    if (rmesa->radeon.TclFallback) {
588       radeonChooseRenderState( ctx );
589       radeonChooseVertexState( ctx );
590    }
591 }
592
593
594 /* =============================================================
595  * Rendering attributes
596  *
597  * We really don't want to recalculate all this every time we bind a
598  * texture.  These things shouldn't change all that often, so it makes
599  * sense to break them out of the core texture state update routines.
600  */
601
602 /* Examine lighting and texture state to determine if separate specular
603  * should be enabled.
604  */
605 static void radeonUpdateSpecular( struct gl_context *ctx )
606 {
607    r100ContextPtr rmesa = R100_CONTEXT(ctx);
608    uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
609    GLuint flag = 0;
610
611    RADEON_STATECHANGE( rmesa, tcl );
612
613    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
614    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
615    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
616    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE;
617    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
618
619    p &= ~RADEON_SPECULAR_ENABLE;
620
621    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE;
622
623
624    if (ctx->Light.Enabled &&
625        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
626       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
627       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
628       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
629       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
630       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
631       p |=  RADEON_SPECULAR_ENABLE;
632       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
633          ~RADEON_DIFFUSE_SPECULAR_COMBINE;
634    }
635    else if (ctx->Light.Enabled) {
636       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
637       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
638       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
639    } else if (ctx->Fog.ColorSumEnabled ) {
640       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
641       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
642       p |= RADEON_SPECULAR_ENABLE;
643    } else {
644       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
645    }
646
647    if (ctx->Fog.Enabled) {
648       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
649       if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
650          rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
651       /* Bizzare: have to leave lighting enabled to get fog. */
652          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
653       }
654       else {
655       /* cannot do tcl fog factor calculation with fog coord source
656        * (send precomputed factors). Cannot use precomputed fog
657        * factors together with tcl spec light (need tcl fallback) */
658          flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
659             RADEON_TCL_COMPUTE_SPECULAR) != 0;
660       }
661    }
662
663    TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
664
665    if (_mesa_need_secondary_color(ctx)) {
666       assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
667    } else {
668       assert( (p & RADEON_SPECULAR_ENABLE) == 0 );
669    }
670
671    if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
672       RADEON_STATECHANGE( rmesa, ctx );
673       rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
674    }
675
676    /* Update vertex/render formats
677     */
678    if (rmesa->radeon.TclFallback) {
679       radeonChooseRenderState( ctx );
680       radeonChooseVertexState( ctx );
681    }
682 }
683
684
685 /* =============================================================
686  * Materials
687  */
688
689
690 /* Update on colormaterial, material emmissive/ambient,
691  * lightmodel.globalambient
692  */
693 static void update_global_ambient( struct gl_context *ctx )
694 {
695    r100ContextPtr rmesa = R100_CONTEXT(ctx);
696    float *fcmd = (float *)RADEON_DB_STATE( glt );
697
698    /* Need to do more if both emmissive & ambient are PREMULT:
699     * Hope this is not needed for MULT
700     */
701    if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
702        ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
703         (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
704    {
705       COPY_3V( &fcmd[GLT_RED],
706                ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
707       ACC_SCALE_3V( &fcmd[GLT_RED],
708                    ctx->Light.Model.Ambient,
709                    ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
710    }
711    else
712    {
713       COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
714    }
715
716    RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
717 }
718
719 /* Update on change to
720  *    - light[p].colors
721  *    - light[p].enabled
722  */
723 static void update_light_colors( struct gl_context *ctx, GLuint p )
724 {
725    struct gl_light *l = &ctx->Light.Light[p];
726
727 /*     fprintf(stderr, "%s\n", __FUNCTION__); */
728
729    if (l->Enabled) {
730       r100ContextPtr rmesa = R100_CONTEXT(ctx);
731       float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
732
733       COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
734       COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
735       COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
736
737       RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
738    }
739 }
740
741 /* Also fallback for asym colormaterial mode in twoside lighting...
742  */
743 static void check_twoside_fallback( struct gl_context *ctx )
744 {
745    GLboolean fallback = GL_FALSE;
746    GLint i;
747
748    if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
749       if (ctx->Light.ColorMaterialEnabled &&
750           (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
751           ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
752          fallback = GL_TRUE;
753       else {
754          for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
755             if (memcmp( ctx->Light.Material.Attrib[i],
756                         ctx->Light.Material.Attrib[i+1],
757                         sizeof(GLfloat)*4) != 0) {
758                fallback = GL_TRUE;
759                break;
760             }
761       }
762    }
763
764    TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
765 }
766
767
768 static void radeonColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
769 {
770       r100ContextPtr rmesa = R100_CONTEXT(ctx);
771       GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
772
773       light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
774                            (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
775                            (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
776                            (3 << RADEON_SPECULAR_SOURCE_SHIFT));
777
778    if (ctx->Light.ColorMaterialEnabled) {
779       GLuint mask = ctx->Light.ColorMaterialBitmask;
780
781       if (mask & MAT_BIT_FRONT_EMISSION) {
782          light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
783                              RADEON_EMISSIVE_SOURCE_SHIFT);
784       }
785       else {
786          light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
787                              RADEON_EMISSIVE_SOURCE_SHIFT);
788       }
789
790       if (mask & MAT_BIT_FRONT_AMBIENT) {
791          light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
792                              RADEON_AMBIENT_SOURCE_SHIFT);
793       }
794       else {
795          light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
796                              RADEON_AMBIENT_SOURCE_SHIFT);
797       }
798
799       if (mask & MAT_BIT_FRONT_DIFFUSE) {
800          light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
801                              RADEON_DIFFUSE_SOURCE_SHIFT);
802       }
803       else {
804          light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
805                              RADEON_DIFFUSE_SOURCE_SHIFT);
806       }
807
808       if (mask & MAT_BIT_FRONT_SPECULAR) {
809          light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
810                              RADEON_SPECULAR_SOURCE_SHIFT);
811       }
812       else {
813          light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
814                              RADEON_SPECULAR_SOURCE_SHIFT);
815       }
816    }
817    else {
818    /* Default to MULT:
819     */
820       light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
821                    (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
822                    (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
823                    (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
824    }
825
826       if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
827          RADEON_STATECHANGE( rmesa, tcl );
828          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
829    }
830 }
831
832 void radeonUpdateMaterial( struct gl_context *ctx )
833 {
834    r100ContextPtr rmesa = R100_CONTEXT(ctx);
835    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
836    GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
837    GLuint mask = ~0;
838
839    if (ctx->Light.ColorMaterialEnabled)
840       mask &= ~ctx->Light.ColorMaterialBitmask;
841
842    if (RADEON_DEBUG & RADEON_STATE)
843       fprintf(stderr, "%s\n", __FUNCTION__);
844
845
846    if (mask & MAT_BIT_FRONT_EMISSION) {
847       fcmd[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_FRONT_EMISSION][0];
848       fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
849       fcmd[MTL_EMMISSIVE_BLUE]  = mat[MAT_ATTRIB_FRONT_EMISSION][2];
850       fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
851    }
852    if (mask & MAT_BIT_FRONT_AMBIENT) {
853       fcmd[MTL_AMBIENT_RED]     = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
854       fcmd[MTL_AMBIENT_GREEN]   = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
855       fcmd[MTL_AMBIENT_BLUE]    = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
856       fcmd[MTL_AMBIENT_ALPHA]   = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
857    }
858    if (mask & MAT_BIT_FRONT_DIFFUSE) {
859       fcmd[MTL_DIFFUSE_RED]     = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
860       fcmd[MTL_DIFFUSE_GREEN]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
861       fcmd[MTL_DIFFUSE_BLUE]    = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
862       fcmd[MTL_DIFFUSE_ALPHA]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
863    }
864    if (mask & MAT_BIT_FRONT_SPECULAR) {
865       fcmd[MTL_SPECULAR_RED]    = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
866       fcmd[MTL_SPECULAR_GREEN]  = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
867       fcmd[MTL_SPECULAR_BLUE]   = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
868       fcmd[MTL_SPECULAR_ALPHA]  = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
869    }
870    if (mask & MAT_BIT_FRONT_SHININESS) {
871       fcmd[MTL_SHININESS]       = mat[MAT_ATTRIB_FRONT_SHININESS][0];
872    }
873
874    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl );
875
876    check_twoside_fallback( ctx );
877 /*   update_global_ambient( ctx );*/
878 }
879
880 /* _NEW_LIGHT
881  * _NEW_MODELVIEW
882  * _MESA_NEW_NEED_EYE_COORDS
883  *
884  * Uses derived state from mesa:
885  *       _VP_inf_norm
886  *       _h_inf_norm
887  *       _Position
888  *       _NormSpotDirection
889  *       _ModelViewInvScale
890  *       _NeedEyeCoords
891  *       _EyeZDir
892  *
893  * which are calculated in light.c and are correct for the current
894  * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
895  * and _MESA_NEW_NEED_EYE_COORDS.
896  */
897 static void update_light( struct gl_context *ctx )
898 {
899    r100ContextPtr rmesa = R100_CONTEXT(ctx);
900
901    /* Have to check these, or have an automatic shortcircuit mechanism
902     * to remove noop statechanges. (Or just do a better job on the
903     * front end).
904     */
905    {
906       GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
907
908       if (ctx->_NeedEyeCoords)
909          tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
910       else
911          tmp |= RADEON_LIGHT_IN_MODELSPACE;
912
913
914       /* Leave this test disabled: (unexplained q3 lockup) (even with
915          new packets)
916       */
917       if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
918       {
919          RADEON_STATECHANGE( rmesa, tcl );
920          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
921       }
922    }
923
924    {
925       GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
926       fcmd[EYE_X] = ctx->_EyeZDir[0];
927       fcmd[EYE_Y] = ctx->_EyeZDir[1];
928       fcmd[EYE_Z] = - ctx->_EyeZDir[2];
929       fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
930       RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
931    }
932
933
934
935    if (ctx->Light.Enabled) {
936       GLint p;
937       for (p = 0 ; p < MAX_LIGHTS; p++) {
938          if (ctx->Light.Light[p].Enabled) {
939             struct gl_light *l = &ctx->Light.Light[p];
940             GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
941
942             if (l->EyePosition[3] == 0.0) {
943                COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
944                COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
945                fcmd[LIT_POSITION_W] = 0;
946                fcmd[LIT_DIRECTION_W] = 0;
947             } else {
948                COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
949                fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
950                fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
951                fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
952                fcmd[LIT_DIRECTION_W] = 0;
953             }
954
955             RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
956          }
957       }
958    }
959 }
960
961 static void radeonLightfv( struct gl_context *ctx, GLenum light,
962                            GLenum pname, const GLfloat *params )
963 {
964    r100ContextPtr rmesa = R100_CONTEXT(ctx);
965    GLint p = light - GL_LIGHT0;
966    struct gl_light *l = &ctx->Light.Light[p];
967    GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
968
969
970    switch (pname) {
971    case GL_AMBIENT:
972    case GL_DIFFUSE:
973    case GL_SPECULAR:
974       update_light_colors( ctx, p );
975       break;
976
977    case GL_SPOT_DIRECTION:
978       /* picked up in update_light */
979       break;
980
981    case GL_POSITION: {
982       /* positions picked up in update_light, but can do flag here */
983       GLuint flag;
984       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
985
986       /* FIXME: Set RANGE_ATTEN only when needed */
987       if (p&1)
988          flag = RADEON_LIGHT_1_IS_LOCAL;
989       else
990          flag = RADEON_LIGHT_0_IS_LOCAL;
991
992       RADEON_STATECHANGE(rmesa, tcl);
993       if (l->EyePosition[3] != 0.0F)
994          rmesa->hw.tcl.cmd[idx] |= flag;
995       else
996          rmesa->hw.tcl.cmd[idx] &= ~flag;
997       break;
998    }
999
1000    case GL_SPOT_EXPONENT:
1001       RADEON_STATECHANGE(rmesa, lit[p]);
1002       fcmd[LIT_SPOT_EXPONENT] = params[0];
1003       break;
1004
1005    case GL_SPOT_CUTOFF: {
1006       GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
1007       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1008
1009       RADEON_STATECHANGE(rmesa, lit[p]);
1010       fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
1011
1012       RADEON_STATECHANGE(rmesa, tcl);
1013       if (l->SpotCutoff != 180.0F)
1014          rmesa->hw.tcl.cmd[idx] |= flag;
1015       else
1016          rmesa->hw.tcl.cmd[idx] &= ~flag;
1017
1018       break;
1019    }
1020
1021    case GL_CONSTANT_ATTENUATION:
1022       RADEON_STATECHANGE(rmesa, lit[p]);
1023       fcmd[LIT_ATTEN_CONST] = params[0];
1024       if ( params[0] == 0.0 )
1025          fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
1026       else
1027          fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
1028       break;
1029    case GL_LINEAR_ATTENUATION:
1030       RADEON_STATECHANGE(rmesa, lit[p]);
1031       fcmd[LIT_ATTEN_LINEAR] = params[0];
1032       break;
1033    case GL_QUADRATIC_ATTENUATION:
1034       RADEON_STATECHANGE(rmesa, lit[p]);
1035       fcmd[LIT_ATTEN_QUADRATIC] = params[0];
1036       break;
1037    default:
1038       return;
1039    }
1040
1041    /* Set RANGE_ATTEN only when needed */
1042    switch (pname) {
1043    case GL_POSITION:
1044    case GL_CONSTANT_ATTENUATION:
1045    case GL_LINEAR_ATTENUATION:
1046    case GL_QUADRATIC_ATTENUATION:
1047    {
1048       GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
1049       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1050       GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1051                                   : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
1052       GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1053                                   : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
1054
1055       if ( l->EyePosition[3] == 0.0F ||
1056            ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1057              fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1058          /* Disable attenuation */
1059          icmd[idx] &= ~atten_flag;
1060       } else {
1061          if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1062             /* Enable only constant portion of attenuation calculation */
1063             icmd[idx] |= ( atten_flag | atten_const_flag );
1064          } else {
1065             /* Enable full attenuation calculation */
1066             icmd[idx] &= ~atten_const_flag;
1067             icmd[idx] |= atten_flag;
1068          }
1069       }
1070
1071       RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1072       break;
1073    }
1074    default:
1075       break;
1076    }
1077 }
1078
1079
1080
1081
1082 static void radeonLightModelfv( struct gl_context *ctx, GLenum pname,
1083                                 const GLfloat *param )
1084 {
1085    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1086
1087    switch (pname) {
1088       case GL_LIGHT_MODEL_AMBIENT:
1089          update_global_ambient( ctx );
1090          break;
1091
1092       case GL_LIGHT_MODEL_LOCAL_VIEWER:
1093          RADEON_STATECHANGE( rmesa, tcl );
1094          if (ctx->Light.Model.LocalViewer)
1095             rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
1096          else
1097             rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
1098          break;
1099
1100       case GL_LIGHT_MODEL_TWO_SIDE:
1101          RADEON_STATECHANGE( rmesa, tcl );
1102          if (ctx->Light.Model.TwoSide)
1103             rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
1104          else
1105             rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
1106
1107          check_twoside_fallback( ctx );
1108
1109          if (rmesa->radeon.TclFallback) {
1110             radeonChooseRenderState( ctx );
1111             radeonChooseVertexState( ctx );
1112          }
1113          break;
1114
1115       case GL_LIGHT_MODEL_COLOR_CONTROL:
1116          radeonUpdateSpecular(ctx);
1117          break;
1118
1119       default:
1120          break;
1121    }
1122 }
1123
1124 static void radeonShadeModel( struct gl_context *ctx, GLenum mode )
1125 {
1126    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1127    GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1128
1129    s &= ~(RADEON_DIFFUSE_SHADE_MASK |
1130           RADEON_ALPHA_SHADE_MASK |
1131           RADEON_SPECULAR_SHADE_MASK |
1132           RADEON_FOG_SHADE_MASK);
1133
1134    switch ( mode ) {
1135    case GL_FLAT:
1136       s |= (RADEON_DIFFUSE_SHADE_FLAT |
1137             RADEON_ALPHA_SHADE_FLAT |
1138             RADEON_SPECULAR_SHADE_FLAT |
1139             RADEON_FOG_SHADE_FLAT);
1140       break;
1141    case GL_SMOOTH:
1142       s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
1143             RADEON_ALPHA_SHADE_GOURAUD |
1144             RADEON_SPECULAR_SHADE_GOURAUD |
1145             RADEON_FOG_SHADE_GOURAUD);
1146       break;
1147    default:
1148       return;
1149    }
1150
1151    if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1152       RADEON_STATECHANGE( rmesa, set );
1153       rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1154    }
1155 }
1156
1157
1158 /* =============================================================
1159  * User clip planes
1160  */
1161
1162 static void radeonClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1163 {
1164    GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1165    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1166    GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1167
1168    RADEON_STATECHANGE( rmesa, ucp[p] );
1169    rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1170    rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1171    rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1172    rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1173 }
1174
1175 static void radeonUpdateClipPlanes( struct gl_context *ctx )
1176 {
1177    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1178    GLuint p;
1179
1180    for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1181       if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1182          GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1183
1184          RADEON_STATECHANGE( rmesa, ucp[p] );
1185          rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1186          rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1187          rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1188          rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1189       }
1190    }
1191 }
1192
1193
1194 /* =============================================================
1195  * Stencil
1196  */
1197
1198 static void
1199 radeonStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1200                            GLint ref, GLuint mask )
1201 {
1202    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1203    GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) |
1204                      ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
1205
1206    RADEON_STATECHANGE( rmesa, ctx );
1207    RADEON_STATECHANGE( rmesa, msk );
1208
1209    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
1210    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
1211                                                    RADEON_STENCIL_VALUE_MASK);
1212
1213    switch ( ctx->Stencil.Function[0] ) {
1214    case GL_NEVER:
1215       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
1216       break;
1217    case GL_LESS:
1218       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
1219       break;
1220    case GL_EQUAL:
1221       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
1222       break;
1223    case GL_LEQUAL:
1224       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
1225       break;
1226    case GL_GREATER:
1227       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
1228       break;
1229    case GL_NOTEQUAL:
1230       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
1231       break;
1232    case GL_GEQUAL:
1233       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
1234       break;
1235    case GL_ALWAYS:
1236       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
1237       break;
1238    }
1239
1240    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1241 }
1242
1243 static void
1244 radeonStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1245 {
1246    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1247
1248    RADEON_STATECHANGE( rmesa, msk );
1249    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
1250    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1251       ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
1252 }
1253
1254 static void radeonStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1255                                      GLenum zfail, GLenum zpass )
1256 {
1257    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1258
1259    /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1260       and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1261       but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1262
1263    GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
1264    GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
1265    GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1266    GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1267    GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1268    GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
1269
1270    if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
1271       tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
1272       tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
1273       tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
1274       tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
1275       tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
1276       tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
1277    }
1278    else {
1279       tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
1280       tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
1281       tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
1282       tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
1283       tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
1284       tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
1285    }
1286
1287    RADEON_STATECHANGE( rmesa, ctx );
1288    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1289                                                RADEON_STENCIL_ZFAIL_MASK |
1290                                                RADEON_STENCIL_ZPASS_MASK);
1291
1292    switch ( ctx->Stencil.FailFunc[0] ) {
1293    case GL_KEEP:
1294       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1295       break;
1296    case GL_ZERO:
1297       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1298       break;
1299    case GL_REPLACE:
1300       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1301       break;
1302    case GL_INCR:
1303       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1304       break;
1305    case GL_DECR:
1306       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1307       break;
1308    case GL_INCR_WRAP:
1309       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
1310       break;
1311    case GL_DECR_WRAP:
1312       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
1313       break;
1314    case GL_INVERT:
1315       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1316       break;
1317    }
1318
1319    switch ( ctx->Stencil.ZFailFunc[0] ) {
1320    case GL_KEEP:
1321       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1322       break;
1323    case GL_ZERO:
1324       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1325       break;
1326    case GL_REPLACE:
1327       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1328       break;
1329    case GL_INCR:
1330       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1331       break;
1332    case GL_DECR:
1333       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1334       break;
1335    case GL_INCR_WRAP:
1336       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1337       break;
1338    case GL_DECR_WRAP:
1339       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1340       break;
1341    case GL_INVERT:
1342       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1343       break;
1344    }
1345
1346    switch ( ctx->Stencil.ZPassFunc[0] ) {
1347    case GL_KEEP:
1348       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1349       break;
1350    case GL_ZERO:
1351       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1352       break;
1353    case GL_REPLACE:
1354       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1355       break;
1356    case GL_INCR:
1357       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1358       break;
1359    case GL_DECR:
1360       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1361       break;
1362    case GL_INCR_WRAP:
1363       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
1364       break;
1365    case GL_DECR_WRAP:
1366       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1367       break;
1368    case GL_INVERT:
1369       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1370       break;
1371    }
1372 }
1373
1374 static void radeonClearStencil( struct gl_context *ctx, GLint s )
1375 {
1376    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1377
1378    rmesa->radeon.state.stencil.clear =
1379       ((GLuint) (ctx->Stencil.Clear & 0xff) |
1380        (0xff << RADEON_STENCIL_MASK_SHIFT) |
1381        ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT));
1382 }
1383
1384
1385 /* =============================================================
1386  * Window position and viewport transformation
1387  */
1388
1389 /*
1390  * To correctly position primitives:
1391  */
1392 #define SUBPIXEL_X 0.125
1393 #define SUBPIXEL_Y 0.125
1394
1395
1396 /**
1397  * Called when window size or position changes or viewport or depth range
1398  * state is changed.  We update the hardware viewport state here.
1399  */
1400 void radeonUpdateWindow( struct gl_context *ctx )
1401 {
1402    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1403    __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1404    GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
1405    GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
1406    const GLfloat *v = ctx->Viewport._WindowMap.m;
1407    const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
1408    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1409    GLfloat y_scale, y_bias;
1410
1411    if (render_to_fbo) {
1412       y_scale = 1.0;
1413       y_bias = 0;
1414    } else {
1415       y_scale = -1.0;
1416       y_bias = yoffset;
1417    }
1418
1419    float_ui32_type sx = { v[MAT_SX] };
1420    float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
1421    float_ui32_type sy = { v[MAT_SY] * y_scale };
1422    float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
1423    float_ui32_type sz = { v[MAT_SZ] * depthScale };
1424    float_ui32_type tz = { v[MAT_TZ] * depthScale };
1425
1426    RADEON_STATECHANGE( rmesa, vpt );
1427
1428    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = sx.ui32;
1429    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1430    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE]  = sy.ui32;
1431    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1432    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE]  = sz.ui32;
1433    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1434 }
1435
1436
1437 static void radeonViewport( struct gl_context *ctx, GLint x, GLint y,
1438                             GLsizei width, GLsizei height )
1439 {
1440    /* Don't pipeline viewport changes, conflict with window offset
1441     * setting below.  Could apply deltas to rescue pipelined viewport
1442     * values, or keep the originals hanging around.
1443     */
1444    radeonUpdateWindow( ctx );
1445
1446    radeon_viewport(ctx, x, y, width, height);
1447 }
1448
1449 static void radeonDepthRange( struct gl_context *ctx, GLclampd nearval,
1450                               GLclampd farval )
1451 {
1452    radeonUpdateWindow( ctx );
1453 }
1454
1455 void radeonUpdateViewportOffset( struct gl_context *ctx )
1456 {
1457    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1458    __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1459    GLfloat xoffset = (GLfloat)dPriv->x;
1460    GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1461    const GLfloat *v = ctx->Viewport._WindowMap.m;
1462
1463    float_ui32_type tx;
1464    float_ui32_type ty;
1465
1466    tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X;
1467    ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1468
1469    if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
1470         rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
1471    {
1472       /* Note: this should also modify whatever data the context reset
1473        * code uses...
1474        */
1475       RADEON_STATECHANGE( rmesa, vpt );
1476       rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1477       rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1478
1479       /* update polygon stipple x/y screen offset */
1480       {
1481          GLuint stx, sty;
1482          GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1483
1484          m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
1485                 RADEON_STIPPLE_Y_OFFSET_MASK);
1486
1487          /* add magic offsets, then invert */
1488          stx = 31 - ((dPriv->x - 1) & RADEON_STIPPLE_COORD_MASK);
1489          sty = 31 - ((dPriv->y + dPriv->h - 1)
1490                      & RADEON_STIPPLE_COORD_MASK);
1491
1492          m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
1493                (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
1494
1495          if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1496             RADEON_STATECHANGE( rmesa, msc );
1497             rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1498          }
1499       }
1500    }
1501
1502    radeonUpdateScissor( ctx );
1503 }
1504
1505
1506
1507 /* =============================================================
1508  * Miscellaneous
1509  */
1510
1511 static void radeonClearColor( struct gl_context *ctx, const GLfloat color[4] )
1512 {
1513    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1514    GLubyte c[4];
1515    struct radeon_renderbuffer *rrb;
1516
1517    rrb = radeon_get_colorbuffer(&rmesa->radeon);
1518    if (!rrb)
1519      return;
1520      
1521    CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
1522    CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
1523    CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
1524    CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
1525    rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
1526                                                c[0], c[1], c[2], c[3] );
1527 }
1528
1529
1530 static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
1531 {
1532    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1533    FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1534 }
1535
1536
1537 static GLuint radeon_rop_tab[] = {
1538    RADEON_ROP_CLEAR,
1539    RADEON_ROP_AND,
1540    RADEON_ROP_AND_REVERSE,
1541    RADEON_ROP_COPY,
1542    RADEON_ROP_AND_INVERTED,
1543    RADEON_ROP_NOOP,
1544    RADEON_ROP_XOR,
1545    RADEON_ROP_OR,
1546    RADEON_ROP_NOR,
1547    RADEON_ROP_EQUIV,
1548    RADEON_ROP_INVERT,
1549    RADEON_ROP_OR_REVERSE,
1550    RADEON_ROP_COPY_INVERTED,
1551    RADEON_ROP_OR_INVERTED,
1552    RADEON_ROP_NAND,
1553    RADEON_ROP_SET,
1554 };
1555
1556 static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode )
1557 {
1558    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1559    GLuint rop = (GLuint)opcode - GL_CLEAR;
1560
1561    ASSERT( rop < 16 );
1562
1563    RADEON_STATECHANGE( rmesa, msk );
1564    rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1565 }
1566
1567 /* =============================================================
1568  * State enable/disable
1569  */
1570
1571 static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
1572 {
1573    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1574    GLuint p, flag;
1575
1576    if ( RADEON_DEBUG & RADEON_STATE )
1577       fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1578                _mesa_lookup_enum_by_nr( cap ),
1579                state ? "GL_TRUE" : "GL_FALSE" );
1580
1581    switch ( cap ) {
1582       /* Fast track this one...
1583        */
1584    case GL_TEXTURE_1D:
1585    case GL_TEXTURE_2D:
1586    case GL_TEXTURE_3D:
1587       break;
1588
1589    case GL_ALPHA_TEST:
1590       RADEON_STATECHANGE( rmesa, ctx );
1591       if (state) {
1592          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1593       } else {
1594          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1595       }
1596       break;
1597
1598    case GL_BLEND:
1599       RADEON_STATECHANGE( rmesa, ctx );
1600       if (state) {
1601          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ALPHA_BLEND_ENABLE;
1602       } else {
1603          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1604       }
1605       if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1606             && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1607          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
1608       } else {
1609          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1610       }
1611
1612       /* Catch a possible fallback:
1613        */
1614       if (state) {
1615          ctx->Driver.BlendEquationSeparate( ctx,
1616                                             ctx->Color.Blend[0].EquationRGB,
1617                                             ctx->Color.Blend[0].EquationA );
1618          ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
1619                                         ctx->Color.Blend[0].DstRGB,
1620                                         ctx->Color.Blend[0].SrcA,
1621                                         ctx->Color.Blend[0].DstA );
1622       }
1623       else {
1624          FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1625          FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1626       }
1627       break;
1628
1629    case GL_CLIP_PLANE0:
1630    case GL_CLIP_PLANE1:
1631    case GL_CLIP_PLANE2:
1632    case GL_CLIP_PLANE3:
1633    case GL_CLIP_PLANE4:
1634    case GL_CLIP_PLANE5:
1635       p = cap-GL_CLIP_PLANE0;
1636       RADEON_STATECHANGE( rmesa, tcl );
1637       if (state) {
1638          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1639          radeonClipPlane( ctx, cap, NULL );
1640       }
1641       else {
1642          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1643       }
1644       break;
1645
1646    case GL_COLOR_MATERIAL:
1647       radeonColorMaterial( ctx, 0, 0 );
1648       radeonUpdateMaterial( ctx );
1649       break;
1650
1651    case GL_CULL_FACE:
1652       radeonCullFace( ctx, 0 );
1653       break;
1654
1655    case GL_DEPTH_TEST:
1656       RADEON_STATECHANGE(rmesa, ctx );
1657       if ( state ) {
1658          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_Z_ENABLE;
1659       } else {
1660          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1661       }
1662       break;
1663
1664    case GL_DITHER:
1665       RADEON_STATECHANGE(rmesa, ctx );
1666       if ( state ) {
1667          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_DITHER_ENABLE;
1668          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1669       } else {
1670          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1671          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  rmesa->radeon.state.color.roundEnable;
1672       }
1673       break;
1674
1675    case GL_FOG:
1676       RADEON_STATECHANGE(rmesa, ctx );
1677       if ( state ) {
1678          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1679          radeonFogfv( ctx, GL_FOG_MODE, NULL );
1680       } else {
1681          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1682          RADEON_STATECHANGE(rmesa, tcl);
1683          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1684       }
1685       radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1686       _mesa_allow_light_in_model( ctx, !state );
1687       break;
1688
1689    case GL_LIGHT0:
1690    case GL_LIGHT1:
1691    case GL_LIGHT2:
1692    case GL_LIGHT3:
1693    case GL_LIGHT4:
1694    case GL_LIGHT5:
1695    case GL_LIGHT6:
1696    case GL_LIGHT7:
1697       RADEON_STATECHANGE(rmesa, tcl);
1698       p = cap - GL_LIGHT0;
1699       if (p&1)
1700          flag = (RADEON_LIGHT_1_ENABLE |
1701                  RADEON_LIGHT_1_ENABLE_AMBIENT |
1702                  RADEON_LIGHT_1_ENABLE_SPECULAR);
1703       else
1704          flag = (RADEON_LIGHT_0_ENABLE |
1705                  RADEON_LIGHT_0_ENABLE_AMBIENT |
1706                  RADEON_LIGHT_0_ENABLE_SPECULAR);
1707
1708       if (state)
1709          rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1710       else
1711          rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1712
1713       /*
1714        */
1715       update_light_colors( ctx, p );
1716       break;
1717
1718    case GL_LIGHTING:
1719       RADEON_STATECHANGE(rmesa, tcl);
1720       radeonUpdateSpecular(ctx);
1721       check_twoside_fallback( ctx );
1722       break;
1723
1724    case GL_LINE_SMOOTH:
1725       RADEON_STATECHANGE( rmesa, ctx );
1726       if ( state ) {
1727          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_LINE;
1728       } else {
1729          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1730       }
1731       break;
1732
1733    case GL_LINE_STIPPLE:
1734       RADEON_STATECHANGE( rmesa, ctx );
1735       if ( state ) {
1736          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_PATTERN_ENABLE;
1737       } else {
1738          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1739       }
1740       break;
1741
1742    case GL_COLOR_LOGIC_OP:
1743       RADEON_STATECHANGE( rmesa, ctx );
1744       if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1745             && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1746          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
1747       } else {
1748          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1749       }
1750       break;
1751
1752    case GL_NORMALIZE:
1753       RADEON_STATECHANGE( rmesa, tcl );
1754       if ( state ) {
1755          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_NORMALIZE_NORMALS;
1756       } else {
1757          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1758       }
1759       break;
1760
1761    case GL_POLYGON_OFFSET_POINT:
1762       RADEON_STATECHANGE( rmesa, set );
1763       if ( state ) {
1764          rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_POINT;
1765       } else {
1766          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1767       }
1768       break;
1769
1770    case GL_POLYGON_OFFSET_LINE:
1771       RADEON_STATECHANGE( rmesa, set );
1772       if ( state ) {
1773          rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_LINE;
1774       } else {
1775          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1776       }
1777       break;
1778
1779    case GL_POLYGON_OFFSET_FILL:
1780       RADEON_STATECHANGE( rmesa, set );
1781       if ( state ) {
1782          rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_TRI;
1783       } else {
1784          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1785       }
1786       break;
1787
1788    case GL_POLYGON_SMOOTH:
1789       RADEON_STATECHANGE( rmesa, ctx );
1790       if ( state ) {
1791          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_POLY;
1792       } else {
1793          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1794       }
1795       break;
1796
1797    case GL_POLYGON_STIPPLE:
1798       RADEON_STATECHANGE(rmesa, ctx );
1799       if ( state ) {
1800          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_STIPPLE_ENABLE;
1801       } else {
1802          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1803       }
1804       break;
1805
1806    case GL_RESCALE_NORMAL_EXT: {
1807       GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1808       RADEON_STATECHANGE( rmesa, tcl );
1809       if ( tmp ) {
1810          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
1811       } else {
1812          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1813       }
1814       break;
1815    }
1816
1817    case GL_SCISSOR_TEST:
1818       radeon_firevertices(&rmesa->radeon);
1819       rmesa->radeon.state.scissor.enabled = state;
1820       radeonUpdateScissor( ctx );
1821       break;
1822
1823    case GL_STENCIL_TEST:
1824       {
1825          GLboolean hw_stencil = GL_FALSE;
1826          if (ctx->DrawBuffer) {
1827             struct radeon_renderbuffer *rrbStencil
1828                = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1829             hw_stencil = (rrbStencil && rrbStencil->bo);
1830          }
1831
1832          if (hw_stencil) {
1833             RADEON_STATECHANGE( rmesa, ctx );
1834             if ( state ) {
1835                rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_STENCIL_ENABLE;
1836             } else {
1837                rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1838             }
1839          } else {
1840             FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1841          }
1842       }
1843       break;
1844
1845    case GL_TEXTURE_GEN_Q:
1846    case GL_TEXTURE_GEN_R:
1847    case GL_TEXTURE_GEN_S:
1848    case GL_TEXTURE_GEN_T:
1849       /* Picked up in radeonUpdateTextureState.
1850        */
1851       rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1852       break;
1853
1854    case GL_COLOR_SUM_EXT:
1855       radeonUpdateSpecular ( ctx );
1856       break;
1857
1858    default:
1859       return;
1860    }
1861 }
1862
1863
1864 static void radeonLightingSpaceChange( struct gl_context *ctx )
1865 {
1866    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1867    GLboolean tmp;
1868    RADEON_STATECHANGE( rmesa, tcl );
1869
1870    if (RADEON_DEBUG & RADEON_STATE)
1871       fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1872               rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1873
1874    if (ctx->_NeedEyeCoords)
1875       tmp = ctx->Transform.RescaleNormals;
1876    else
1877       tmp = !ctx->Transform.RescaleNormals;
1878
1879    if ( tmp ) {
1880       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
1881    } else {
1882       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1883    }
1884
1885    if (RADEON_DEBUG & RADEON_STATE)
1886       fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1887               rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1888 }
1889
1890 /* =============================================================
1891  * Deferred state management - matrices, textures, other?
1892  */
1893
1894
1895 void radeonUploadTexMatrix( r100ContextPtr rmesa,
1896                             int unit, GLboolean swapcols )
1897 {
1898 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1899    vector looks like this probably: (s t r|q 0) (not sure if the last coord
1900    is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1901    texgen generates all 4 coords, at least tests with projtex indicated that.
1902    So: if we need the q coord in the end (solely determined by the texture
1903    target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1904    Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1905    column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1906    will get submitted in the "wrong", i.e. 3rd, slot.
1907    If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1908    size and using the texture matrix to swap the r and q coords around (ut2k3
1909    does exactly that), so we don't need the 3rd / 4th column swap - still need
1910    the 3rd / 4th row swap of course. This will potentially break for apps which
1911    use TexCoord3x just for fun. Additionally, it will never work if an app uses
1912    an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1913    the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1914    incredibly hard to detect so we can't just fallback in such a case. Assume
1915    it never happens... - rs
1916 */
1917
1918    int idx = TEXMAT_0 + unit;
1919    float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1920    int i;
1921    struct gl_texture_unit tUnit = rmesa->radeon.glCtx->Texture.Unit[unit];
1922    GLfloat *src = rmesa->tmpmat[unit].m;
1923
1924    rmesa->TexMatColSwap &= ~(1 << unit);
1925    if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
1926       if (swapcols) {
1927          rmesa->TexMatColSwap |= 1 << unit;
1928          /* attention some elems are swapped 2 times! */
1929          *dest++ = src[0];
1930          *dest++ = src[4];
1931          *dest++ = src[12];
1932          *dest++ = src[8];
1933          *dest++ = src[1];
1934          *dest++ = src[5];
1935          *dest++ = src[13];
1936          *dest++ = src[9];
1937          *dest++ = src[2];
1938          *dest++ = src[6];
1939          *dest++ = src[15];
1940          *dest++ = src[11];
1941          /* those last 4 are probably never used */
1942          *dest++ = src[3];
1943          *dest++ = src[7];
1944          *dest++ = src[14];
1945          *dest++ = src[10];
1946       }
1947       else {
1948          for (i = 0; i < 2; i++) {
1949             *dest++ = src[i];
1950             *dest++ = src[i+4];
1951             *dest++ = src[i+8];
1952             *dest++ = src[i+12];
1953          }
1954          for (i = 3; i >= 2; i--) {
1955             *dest++ = src[i];
1956             *dest++ = src[i+4];
1957             *dest++ = src[i+8];
1958             *dest++ = src[i+12];
1959          }
1960       }
1961    }
1962    else {
1963       for (i = 0 ; i < 4 ; i++) {
1964          *dest++ = src[i];
1965          *dest++ = src[i+4];
1966          *dest++ = src[i+8];
1967          *dest++ = src[i+12];
1968       }
1969    }
1970
1971    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1972 }
1973
1974
1975 static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1976 {
1977    float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1978    int i;
1979
1980
1981    for (i = 0 ; i < 4 ; i++) {
1982       *dest++ = src[i];
1983       *dest++ = src[i+4];
1984       *dest++ = src[i+8];
1985       *dest++ = src[i+12];
1986    }
1987
1988    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1989 }
1990
1991 static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1992 {
1993    float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1994    memcpy(dest, src, 16*sizeof(float));
1995    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1996 }
1997
1998
1999 static void update_texturematrix( struct gl_context *ctx )
2000 {
2001    r100ContextPtr rmesa = R100_CONTEXT( ctx );
2002    GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
2003    GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
2004    int unit;
2005    GLuint texMatEnabled = 0;
2006    rmesa->NeedTexMatrix = 0;
2007    rmesa->TexMatColSwap = 0;
2008
2009    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
2010       if (ctx->Texture.Unit[unit]._ReallyEnabled) {
2011          GLboolean needMatrix = GL_FALSE;
2012          if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2013             needMatrix = GL_TRUE;
2014             texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
2015                               RADEON_TEXMAT_0_ENABLE) << unit;
2016
2017             if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2018                /* Need to preconcatenate any active texgen
2019                 * obj/eyeplane matrices:
2020                 */
2021                _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
2022                                      ctx->TextureMatrixStack[unit].Top,
2023                                      &rmesa->TexGenMatrix[unit] );
2024             }
2025             else {
2026                _math_matrix_copy( &rmesa->tmpmat[unit],
2027                   ctx->TextureMatrixStack[unit].Top );
2028             }
2029          }
2030          else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2031             _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
2032             needMatrix = GL_TRUE;
2033          }
2034          if (needMatrix) {
2035             rmesa->NeedTexMatrix |= 1 << unit;
2036             radeonUploadTexMatrix( rmesa, unit,
2037                         !ctx->Texture.Unit[unit].TexGenEnabled );
2038          }
2039       }
2040    }
2041
2042    tpc = (texMatEnabled | rmesa->TexGenEnabled);
2043
2044    /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2045    vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
2046            (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
2047            (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
2048
2049    vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
2050          (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
2051       ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
2052          (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
2053       ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
2054          (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
2055
2056    if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
2057        vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
2058
2059       RADEON_STATECHANGE(rmesa, tcl);
2060       rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
2061       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
2062    }
2063 }
2064
2065 static GLboolean r100ValidateBuffers(struct gl_context *ctx)
2066 {
2067    r100ContextPtr rmesa = R100_CONTEXT(ctx);
2068    struct radeon_renderbuffer *rrb;
2069    int i, ret;
2070
2071    radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2072
2073    rrb = radeon_get_colorbuffer(&rmesa->radeon);
2074    /* color buffer */
2075    if (rrb && rrb->bo) {
2076      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2077                                        0, RADEON_GEM_DOMAIN_VRAM);
2078    }
2079
2080    /* depth buffer */
2081    rrb = radeon_get_depthbuffer(&rmesa->radeon);
2082    /* color buffer */
2083    if (rrb && rrb->bo) {
2084      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2085                                        0, RADEON_GEM_DOMAIN_VRAM);
2086    }
2087
2088    for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
2089       radeonTexObj *t;
2090
2091       if (!ctx->Texture.Unit[i]._ReallyEnabled)
2092          continue;
2093
2094       t = rmesa->state.texture.unit[i].texobj;
2095
2096       if (!t)
2097          continue;
2098       if (t->image_override && t->bo)
2099         radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2100                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2101       else if (t->mt->bo)
2102         radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2103                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2104    }
2105
2106    ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
2107    if (ret)
2108        return GL_FALSE;
2109    return GL_TRUE;
2110 }
2111
2112 GLboolean radeonValidateState( struct gl_context *ctx )
2113 {
2114    r100ContextPtr rmesa = R100_CONTEXT(ctx);
2115    GLuint new_state = rmesa->radeon.NewGLState;
2116
2117    if (new_state & _NEW_BUFFERS) {
2118      _mesa_update_framebuffer(ctx);
2119      /* this updates the DrawBuffer's Width/Height if it's a FBO */
2120      _mesa_update_draw_buffer_bounds(ctx);
2121      RADEON_STATECHANGE(rmesa, ctx);
2122    }
2123
2124    if (new_state & _NEW_TEXTURE) {
2125       radeonUpdateTextureState( ctx );
2126       new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2127    }
2128
2129    /* we need to do a space check here */
2130    if (!r100ValidateBuffers(ctx))
2131      return GL_FALSE;
2132
2133    /* Need an event driven matrix update?
2134     */
2135    if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2136       upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2137
2138    /* Need these for lighting (shouldn't upload otherwise)
2139     */
2140    if (new_state & (_NEW_MODELVIEW)) {
2141       upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2142       upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2143    }
2144
2145    /* Does this need to be triggered on eg. modelview for
2146     * texgen-derived objplane/eyeplane matrices?
2147     */
2148    if (new_state & _NEW_TEXTURE_MATRIX) {
2149       update_texturematrix( ctx );
2150    }
2151
2152    if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2153       update_light( ctx );
2154    }
2155
2156    /* emit all active clip planes if projection matrix changes.
2157     */
2158    if (new_state & (_NEW_PROJECTION)) {
2159       if (ctx->Transform.ClipPlanesEnabled)
2160          radeonUpdateClipPlanes( ctx );
2161    }
2162
2163
2164    rmesa->radeon.NewGLState = 0;
2165
2166    return GL_TRUE;
2167 }
2168
2169
2170 static void radeonInvalidateState( struct gl_context *ctx, GLuint new_state )
2171 {
2172    _swrast_InvalidateState( ctx, new_state );
2173    _swsetup_InvalidateState( ctx, new_state );
2174    _vbo_InvalidateState( ctx, new_state );
2175    _tnl_InvalidateState( ctx, new_state );
2176    _ae_invalidate_state( ctx, new_state );
2177    R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2178 }
2179
2180
2181 /* A hack.  Need a faster way to find this out.
2182  */
2183 static GLboolean check_material( struct gl_context *ctx )
2184 {
2185    TNLcontext *tnl = TNL_CONTEXT(ctx);
2186    GLint i;
2187
2188    for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2189         i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2190         i++)
2191       if (tnl->vb.AttribPtr[i] &&
2192           tnl->vb.AttribPtr[i]->stride)
2193          return GL_TRUE;
2194
2195    return GL_FALSE;
2196 }
2197
2198
2199 static void radeonWrapRunPipeline( struct gl_context *ctx )
2200 {
2201    r100ContextPtr rmesa = R100_CONTEXT(ctx);
2202    GLboolean has_material;
2203
2204    if (0)
2205       fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2206
2207    /* Validate state:
2208     */
2209    if (rmesa->radeon.NewGLState)
2210       if (!radeonValidateState( ctx ))
2211          FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2212
2213    has_material = (ctx->Light.Enabled && check_material( ctx ));
2214
2215    if (has_material) {
2216       TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2217    }
2218
2219    /* Run the pipeline.
2220     */
2221    _tnl_run_pipeline( ctx );
2222
2223    if (has_material) {
2224       TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2225    }
2226 }
2227
2228 static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2229 {
2230    r100ContextPtr r100 = R100_CONTEXT(ctx);
2231    GLint i;
2232
2233    radeon_firevertices(&r100->radeon);
2234
2235    RADEON_STATECHANGE(r100, stp);
2236
2237    /* Must flip pattern upside down.
2238     */
2239    for ( i = 31 ; i >= 0; i--) {
2240      r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2241    }
2242 }
2243
2244
2245 /* Initialize the driver's state functions.
2246  * Many of the ctx->Driver functions might have been initialized to
2247  * software defaults in the earlier _mesa_init_driver_functions() call.
2248  */
2249 void radeonInitStateFuncs( struct gl_context *ctx , GLboolean dri2 )
2250 {
2251    ctx->Driver.UpdateState              = radeonInvalidateState;
2252    ctx->Driver.LightingSpaceChange      = radeonLightingSpaceChange;
2253
2254    ctx->Driver.DrawBuffer               = radeonDrawBuffer;
2255    ctx->Driver.ReadBuffer               = radeonReadBuffer;
2256    ctx->Driver.CopyPixels               = _mesa_meta_CopyPixels;
2257    ctx->Driver.DrawPixels               = _mesa_meta_DrawPixels;
2258    if (dri2)
2259            ctx->Driver.ReadPixels               = radeonReadPixels;
2260
2261    ctx->Driver.AlphaFunc                = radeonAlphaFunc;
2262    ctx->Driver.BlendEquationSeparate    = radeonBlendEquationSeparate;
2263    ctx->Driver.BlendFuncSeparate        = radeonBlendFuncSeparate;
2264    ctx->Driver.ClearColor               = radeonClearColor;
2265    ctx->Driver.ClearDepth               = radeonClearDepth;
2266    ctx->Driver.ClearStencil             = radeonClearStencil;
2267    ctx->Driver.ClipPlane                = radeonClipPlane;
2268    ctx->Driver.ColorMask                = radeonColorMask;
2269    ctx->Driver.CullFace                 = radeonCullFace;
2270    ctx->Driver.DepthFunc                = radeonDepthFunc;
2271    ctx->Driver.DepthMask                = radeonDepthMask;
2272    ctx->Driver.DepthRange               = radeonDepthRange;
2273    ctx->Driver.Enable                   = radeonEnable;
2274    ctx->Driver.Fogfv                    = radeonFogfv;
2275    ctx->Driver.FrontFace                = radeonFrontFace;
2276    ctx->Driver.Hint                     = NULL;
2277    ctx->Driver.LightModelfv             = radeonLightModelfv;
2278    ctx->Driver.Lightfv                  = radeonLightfv;
2279    ctx->Driver.LineStipple              = radeonLineStipple;
2280    ctx->Driver.LineWidth                = radeonLineWidth;
2281    ctx->Driver.LogicOpcode              = radeonLogicOpCode;
2282    ctx->Driver.PolygonMode              = radeonPolygonMode;
2283    ctx->Driver.PolygonOffset            = radeonPolygonOffset;
2284    if (dri2)
2285       ctx->Driver.PolygonStipple                = radeonPolygonStipple;
2286    else
2287       ctx->Driver.PolygonStipple                = radeonPolygonStipplePreKMS;
2288    ctx->Driver.RenderMode               = radeonRenderMode;
2289    ctx->Driver.Scissor                  = radeonScissor;
2290    ctx->Driver.ShadeModel               = radeonShadeModel;
2291    ctx->Driver.StencilFuncSeparate      = radeonStencilFuncSeparate;
2292    ctx->Driver.StencilMaskSeparate      = radeonStencilMaskSeparate;
2293    ctx->Driver.StencilOpSeparate        = radeonStencilOpSeparate;
2294    ctx->Driver.Viewport                 = radeonViewport;
2295
2296    TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2297    TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2298 }