OSDN Git Service

mesa: introduce a clear color union to be used for int/unsigned buffers
[android-x86/external-mesa.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,
1512                               const union gl_color_union color )
1513 {
1514    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1515    GLubyte c[4];
1516    struct radeon_renderbuffer *rrb;
1517
1518    rrb = radeon_get_colorbuffer(&rmesa->radeon);
1519    if (!rrb)
1520      return;
1521      
1522    UNCLAMPED_FLOAT_TO_UBYTE(c[0], color.f[0]);
1523    UNCLAMPED_FLOAT_TO_UBYTE(c[1], color.f[1]);
1524    UNCLAMPED_FLOAT_TO_UBYTE(c[2], color.f[2]);
1525    UNCLAMPED_FLOAT_TO_UBYTE(c[3], color.f[3]);
1526    rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
1527                                                c[0], c[1], c[2], c[3] );
1528 }
1529
1530
1531 static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
1532 {
1533    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1534    FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1535 }
1536
1537
1538 static GLuint radeon_rop_tab[] = {
1539    RADEON_ROP_CLEAR,
1540    RADEON_ROP_AND,
1541    RADEON_ROP_AND_REVERSE,
1542    RADEON_ROP_COPY,
1543    RADEON_ROP_AND_INVERTED,
1544    RADEON_ROP_NOOP,
1545    RADEON_ROP_XOR,
1546    RADEON_ROP_OR,
1547    RADEON_ROP_NOR,
1548    RADEON_ROP_EQUIV,
1549    RADEON_ROP_INVERT,
1550    RADEON_ROP_OR_REVERSE,
1551    RADEON_ROP_COPY_INVERTED,
1552    RADEON_ROP_OR_INVERTED,
1553    RADEON_ROP_NAND,
1554    RADEON_ROP_SET,
1555 };
1556
1557 static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode )
1558 {
1559    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1560    GLuint rop = (GLuint)opcode - GL_CLEAR;
1561
1562    ASSERT( rop < 16 );
1563
1564    RADEON_STATECHANGE( rmesa, msk );
1565    rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1566 }
1567
1568 /* =============================================================
1569  * State enable/disable
1570  */
1571
1572 static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
1573 {
1574    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1575    GLuint p, flag;
1576
1577    if ( RADEON_DEBUG & RADEON_STATE )
1578       fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1579                _mesa_lookup_enum_by_nr( cap ),
1580                state ? "GL_TRUE" : "GL_FALSE" );
1581
1582    switch ( cap ) {
1583       /* Fast track this one...
1584        */
1585    case GL_TEXTURE_1D:
1586    case GL_TEXTURE_2D:
1587    case GL_TEXTURE_3D:
1588       break;
1589
1590    case GL_ALPHA_TEST:
1591       RADEON_STATECHANGE( rmesa, ctx );
1592       if (state) {
1593          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1594       } else {
1595          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1596       }
1597       break;
1598
1599    case GL_BLEND:
1600       RADEON_STATECHANGE( rmesa, ctx );
1601       if (state) {
1602          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ALPHA_BLEND_ENABLE;
1603       } else {
1604          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1605       }
1606       if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1607             && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1608          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
1609       } else {
1610          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1611       }
1612
1613       /* Catch a possible fallback:
1614        */
1615       if (state) {
1616          ctx->Driver.BlendEquationSeparate( ctx,
1617                                             ctx->Color.Blend[0].EquationRGB,
1618                                             ctx->Color.Blend[0].EquationA );
1619          ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
1620                                         ctx->Color.Blend[0].DstRGB,
1621                                         ctx->Color.Blend[0].SrcA,
1622                                         ctx->Color.Blend[0].DstA );
1623       }
1624       else {
1625          FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1626          FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1627       }
1628       break;
1629
1630    case GL_CLIP_PLANE0:
1631    case GL_CLIP_PLANE1:
1632    case GL_CLIP_PLANE2:
1633    case GL_CLIP_PLANE3:
1634    case GL_CLIP_PLANE4:
1635    case GL_CLIP_PLANE5:
1636       p = cap-GL_CLIP_PLANE0;
1637       RADEON_STATECHANGE( rmesa, tcl );
1638       if (state) {
1639          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1640          radeonClipPlane( ctx, cap, NULL );
1641       }
1642       else {
1643          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1644       }
1645       break;
1646
1647    case GL_COLOR_MATERIAL:
1648       radeonColorMaterial( ctx, 0, 0 );
1649       radeonUpdateMaterial( ctx );
1650       break;
1651
1652    case GL_CULL_FACE:
1653       radeonCullFace( ctx, 0 );
1654       break;
1655
1656    case GL_DEPTH_TEST:
1657       RADEON_STATECHANGE(rmesa, ctx );
1658       if ( state ) {
1659          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_Z_ENABLE;
1660       } else {
1661          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1662       }
1663       break;
1664
1665    case GL_DITHER:
1666       RADEON_STATECHANGE(rmesa, ctx );
1667       if ( state ) {
1668          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_DITHER_ENABLE;
1669          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1670       } else {
1671          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1672          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  rmesa->radeon.state.color.roundEnable;
1673       }
1674       break;
1675
1676    case GL_FOG:
1677       RADEON_STATECHANGE(rmesa, ctx );
1678       if ( state ) {
1679          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1680          radeonFogfv( ctx, GL_FOG_MODE, NULL );
1681       } else {
1682          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1683          RADEON_STATECHANGE(rmesa, tcl);
1684          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1685       }
1686       radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1687       _mesa_allow_light_in_model( ctx, !state );
1688       break;
1689
1690    case GL_LIGHT0:
1691    case GL_LIGHT1:
1692    case GL_LIGHT2:
1693    case GL_LIGHT3:
1694    case GL_LIGHT4:
1695    case GL_LIGHT5:
1696    case GL_LIGHT6:
1697    case GL_LIGHT7:
1698       RADEON_STATECHANGE(rmesa, tcl);
1699       p = cap - GL_LIGHT0;
1700       if (p&1)
1701          flag = (RADEON_LIGHT_1_ENABLE |
1702                  RADEON_LIGHT_1_ENABLE_AMBIENT |
1703                  RADEON_LIGHT_1_ENABLE_SPECULAR);
1704       else
1705          flag = (RADEON_LIGHT_0_ENABLE |
1706                  RADEON_LIGHT_0_ENABLE_AMBIENT |
1707                  RADEON_LIGHT_0_ENABLE_SPECULAR);
1708
1709       if (state)
1710          rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1711       else
1712          rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1713
1714       /*
1715        */
1716       update_light_colors( ctx, p );
1717       break;
1718
1719    case GL_LIGHTING:
1720       RADEON_STATECHANGE(rmesa, tcl);
1721       radeonUpdateSpecular(ctx);
1722       check_twoside_fallback( ctx );
1723       break;
1724
1725    case GL_LINE_SMOOTH:
1726       RADEON_STATECHANGE( rmesa, ctx );
1727       if ( state ) {
1728          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_LINE;
1729       } else {
1730          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1731       }
1732       break;
1733
1734    case GL_LINE_STIPPLE:
1735       RADEON_STATECHANGE( rmesa, ctx );
1736       if ( state ) {
1737          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_PATTERN_ENABLE;
1738       } else {
1739          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1740       }
1741       break;
1742
1743    case GL_COLOR_LOGIC_OP:
1744       RADEON_STATECHANGE( rmesa, ctx );
1745       if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1746             && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1747          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
1748       } else {
1749          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1750       }
1751       break;
1752
1753    case GL_NORMALIZE:
1754       RADEON_STATECHANGE( rmesa, tcl );
1755       if ( state ) {
1756          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_NORMALIZE_NORMALS;
1757       } else {
1758          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1759       }
1760       break;
1761
1762    case GL_POLYGON_OFFSET_POINT:
1763       RADEON_STATECHANGE( rmesa, set );
1764       if ( state ) {
1765          rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_POINT;
1766       } else {
1767          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1768       }
1769       break;
1770
1771    case GL_POLYGON_OFFSET_LINE:
1772       RADEON_STATECHANGE( rmesa, set );
1773       if ( state ) {
1774          rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_LINE;
1775       } else {
1776          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1777       }
1778       break;
1779
1780    case GL_POLYGON_OFFSET_FILL:
1781       RADEON_STATECHANGE( rmesa, set );
1782       if ( state ) {
1783          rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_TRI;
1784       } else {
1785          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1786       }
1787       break;
1788
1789    case GL_POLYGON_SMOOTH:
1790       RADEON_STATECHANGE( rmesa, ctx );
1791       if ( state ) {
1792          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_POLY;
1793       } else {
1794          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1795       }
1796       break;
1797
1798    case GL_POLYGON_STIPPLE:
1799       RADEON_STATECHANGE(rmesa, ctx );
1800       if ( state ) {
1801          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_STIPPLE_ENABLE;
1802       } else {
1803          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1804       }
1805       break;
1806
1807    case GL_RESCALE_NORMAL_EXT: {
1808       GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1809       RADEON_STATECHANGE( rmesa, tcl );
1810       if ( tmp ) {
1811          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
1812       } else {
1813          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1814       }
1815       break;
1816    }
1817
1818    case GL_SCISSOR_TEST:
1819       radeon_firevertices(&rmesa->radeon);
1820       rmesa->radeon.state.scissor.enabled = state;
1821       radeonUpdateScissor( ctx );
1822       break;
1823
1824    case GL_STENCIL_TEST:
1825       {
1826          GLboolean hw_stencil = GL_FALSE;
1827          if (ctx->DrawBuffer) {
1828             struct radeon_renderbuffer *rrbStencil
1829                = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1830             hw_stencil = (rrbStencil && rrbStencil->bo);
1831          }
1832
1833          if (hw_stencil) {
1834             RADEON_STATECHANGE( rmesa, ctx );
1835             if ( state ) {
1836                rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_STENCIL_ENABLE;
1837             } else {
1838                rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1839             }
1840          } else {
1841             FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1842          }
1843       }
1844       break;
1845
1846    case GL_TEXTURE_GEN_Q:
1847    case GL_TEXTURE_GEN_R:
1848    case GL_TEXTURE_GEN_S:
1849    case GL_TEXTURE_GEN_T:
1850       /* Picked up in radeonUpdateTextureState.
1851        */
1852       rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1853       break;
1854
1855    case GL_COLOR_SUM_EXT:
1856       radeonUpdateSpecular ( ctx );
1857       break;
1858
1859    default:
1860       return;
1861    }
1862 }
1863
1864
1865 static void radeonLightingSpaceChange( struct gl_context *ctx )
1866 {
1867    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1868    GLboolean tmp;
1869    RADEON_STATECHANGE( rmesa, tcl );
1870
1871    if (RADEON_DEBUG & RADEON_STATE)
1872       fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1873               rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1874
1875    if (ctx->_NeedEyeCoords)
1876       tmp = ctx->Transform.RescaleNormals;
1877    else
1878       tmp = !ctx->Transform.RescaleNormals;
1879
1880    if ( tmp ) {
1881       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
1882    } else {
1883       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1884    }
1885
1886    if (RADEON_DEBUG & RADEON_STATE)
1887       fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1888               rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1889 }
1890
1891 /* =============================================================
1892  * Deferred state management - matrices, textures, other?
1893  */
1894
1895
1896 void radeonUploadTexMatrix( r100ContextPtr rmesa,
1897                             int unit, GLboolean swapcols )
1898 {
1899 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1900    vector looks like this probably: (s t r|q 0) (not sure if the last coord
1901    is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1902    texgen generates all 4 coords, at least tests with projtex indicated that.
1903    So: if we need the q coord in the end (solely determined by the texture
1904    target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1905    Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1906    column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1907    will get submitted in the "wrong", i.e. 3rd, slot.
1908    If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1909    size and using the texture matrix to swap the r and q coords around (ut2k3
1910    does exactly that), so we don't need the 3rd / 4th column swap - still need
1911    the 3rd / 4th row swap of course. This will potentially break for apps which
1912    use TexCoord3x just for fun. Additionally, it will never work if an app uses
1913    an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1914    the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1915    incredibly hard to detect so we can't just fallback in such a case. Assume
1916    it never happens... - rs
1917 */
1918
1919    int idx = TEXMAT_0 + unit;
1920    float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1921    int i;
1922    struct gl_texture_unit tUnit = rmesa->radeon.glCtx->Texture.Unit[unit];
1923    GLfloat *src = rmesa->tmpmat[unit].m;
1924
1925    rmesa->TexMatColSwap &= ~(1 << unit);
1926    if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
1927       if (swapcols) {
1928          rmesa->TexMatColSwap |= 1 << unit;
1929          /* attention some elems are swapped 2 times! */
1930          *dest++ = src[0];
1931          *dest++ = src[4];
1932          *dest++ = src[12];
1933          *dest++ = src[8];
1934          *dest++ = src[1];
1935          *dest++ = src[5];
1936          *dest++ = src[13];
1937          *dest++ = src[9];
1938          *dest++ = src[2];
1939          *dest++ = src[6];
1940          *dest++ = src[15];
1941          *dest++ = src[11];
1942          /* those last 4 are probably never used */
1943          *dest++ = src[3];
1944          *dest++ = src[7];
1945          *dest++ = src[14];
1946          *dest++ = src[10];
1947       }
1948       else {
1949          for (i = 0; i < 2; i++) {
1950             *dest++ = src[i];
1951             *dest++ = src[i+4];
1952             *dest++ = src[i+8];
1953             *dest++ = src[i+12];
1954          }
1955          for (i = 3; i >= 2; i--) {
1956             *dest++ = src[i];
1957             *dest++ = src[i+4];
1958             *dest++ = src[i+8];
1959             *dest++ = src[i+12];
1960          }
1961       }
1962    }
1963    else {
1964       for (i = 0 ; i < 4 ; i++) {
1965          *dest++ = src[i];
1966          *dest++ = src[i+4];
1967          *dest++ = src[i+8];
1968          *dest++ = src[i+12];
1969       }
1970    }
1971
1972    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1973 }
1974
1975
1976 static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1977 {
1978    float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1979    int i;
1980
1981
1982    for (i = 0 ; i < 4 ; i++) {
1983       *dest++ = src[i];
1984       *dest++ = src[i+4];
1985       *dest++ = src[i+8];
1986       *dest++ = src[i+12];
1987    }
1988
1989    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1990 }
1991
1992 static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1993 {
1994    float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1995    memcpy(dest, src, 16*sizeof(float));
1996    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1997 }
1998
1999
2000 static void update_texturematrix( struct gl_context *ctx )
2001 {
2002    r100ContextPtr rmesa = R100_CONTEXT( ctx );
2003    GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
2004    GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
2005    int unit;
2006    GLuint texMatEnabled = 0;
2007    rmesa->NeedTexMatrix = 0;
2008    rmesa->TexMatColSwap = 0;
2009
2010    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
2011       if (ctx->Texture.Unit[unit]._ReallyEnabled) {
2012          GLboolean needMatrix = GL_FALSE;
2013          if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2014             needMatrix = GL_TRUE;
2015             texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
2016                               RADEON_TEXMAT_0_ENABLE) << unit;
2017
2018             if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2019                /* Need to preconcatenate any active texgen
2020                 * obj/eyeplane matrices:
2021                 */
2022                _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
2023                                      ctx->TextureMatrixStack[unit].Top,
2024                                      &rmesa->TexGenMatrix[unit] );
2025             }
2026             else {
2027                _math_matrix_copy( &rmesa->tmpmat[unit],
2028                   ctx->TextureMatrixStack[unit].Top );
2029             }
2030          }
2031          else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2032             _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
2033             needMatrix = GL_TRUE;
2034          }
2035          if (needMatrix) {
2036             rmesa->NeedTexMatrix |= 1 << unit;
2037             radeonUploadTexMatrix( rmesa, unit,
2038                         !ctx->Texture.Unit[unit].TexGenEnabled );
2039          }
2040       }
2041    }
2042
2043    tpc = (texMatEnabled | rmesa->TexGenEnabled);
2044
2045    /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2046    vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
2047            (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
2048            (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
2049
2050    vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
2051          (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
2052       ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
2053          (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
2054       ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
2055          (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
2056
2057    if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
2058        vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
2059
2060       RADEON_STATECHANGE(rmesa, tcl);
2061       rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
2062       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
2063    }
2064 }
2065
2066 static GLboolean r100ValidateBuffers(struct gl_context *ctx)
2067 {
2068    r100ContextPtr rmesa = R100_CONTEXT(ctx);
2069    struct radeon_renderbuffer *rrb;
2070    int i, ret;
2071
2072    radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2073
2074    rrb = radeon_get_colorbuffer(&rmesa->radeon);
2075    /* color buffer */
2076    if (rrb && rrb->bo) {
2077      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2078                                        0, RADEON_GEM_DOMAIN_VRAM);
2079    }
2080
2081    /* depth buffer */
2082    rrb = radeon_get_depthbuffer(&rmesa->radeon);
2083    /* color buffer */
2084    if (rrb && rrb->bo) {
2085      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2086                                        0, RADEON_GEM_DOMAIN_VRAM);
2087    }
2088
2089    for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
2090       radeonTexObj *t;
2091
2092       if (!ctx->Texture.Unit[i]._ReallyEnabled)
2093          continue;
2094
2095       t = rmesa->state.texture.unit[i].texobj;
2096
2097       if (!t)
2098          continue;
2099       if (t->image_override && t->bo)
2100         radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2101                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2102       else if (t->mt->bo)
2103         radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2104                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2105    }
2106
2107    ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
2108    if (ret)
2109        return GL_FALSE;
2110    return GL_TRUE;
2111 }
2112
2113 GLboolean radeonValidateState( struct gl_context *ctx )
2114 {
2115    r100ContextPtr rmesa = R100_CONTEXT(ctx);
2116    GLuint new_state = rmesa->radeon.NewGLState;
2117
2118    if (new_state & _NEW_BUFFERS) {
2119      _mesa_update_framebuffer(ctx);
2120      /* this updates the DrawBuffer's Width/Height if it's a FBO */
2121      _mesa_update_draw_buffer_bounds(ctx);
2122      RADEON_STATECHANGE(rmesa, ctx);
2123    }
2124
2125    if (new_state & _NEW_TEXTURE) {
2126       radeonUpdateTextureState( ctx );
2127       new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2128    }
2129
2130    /* we need to do a space check here */
2131    if (!r100ValidateBuffers(ctx))
2132      return GL_FALSE;
2133
2134    /* Need an event driven matrix update?
2135     */
2136    if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2137       upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2138
2139    /* Need these for lighting (shouldn't upload otherwise)
2140     */
2141    if (new_state & (_NEW_MODELVIEW)) {
2142       upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2143       upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2144    }
2145
2146    /* Does this need to be triggered on eg. modelview for
2147     * texgen-derived objplane/eyeplane matrices?
2148     */
2149    if (new_state & _NEW_TEXTURE_MATRIX) {
2150       update_texturematrix( ctx );
2151    }
2152
2153    if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2154       update_light( ctx );
2155    }
2156
2157    /* emit all active clip planes if projection matrix changes.
2158     */
2159    if (new_state & (_NEW_PROJECTION)) {
2160       if (ctx->Transform.ClipPlanesEnabled)
2161          radeonUpdateClipPlanes( ctx );
2162    }
2163
2164
2165    rmesa->radeon.NewGLState = 0;
2166
2167    return GL_TRUE;
2168 }
2169
2170
2171 static void radeonInvalidateState( struct gl_context *ctx, GLuint new_state )
2172 {
2173    _swrast_InvalidateState( ctx, new_state );
2174    _swsetup_InvalidateState( ctx, new_state );
2175    _vbo_InvalidateState( ctx, new_state );
2176    _tnl_InvalidateState( ctx, new_state );
2177    _ae_invalidate_state( ctx, new_state );
2178    R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2179 }
2180
2181
2182 /* A hack.  Need a faster way to find this out.
2183  */
2184 static GLboolean check_material( struct gl_context *ctx )
2185 {
2186    TNLcontext *tnl = TNL_CONTEXT(ctx);
2187    GLint i;
2188
2189    for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2190         i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2191         i++)
2192       if (tnl->vb.AttribPtr[i] &&
2193           tnl->vb.AttribPtr[i]->stride)
2194          return GL_TRUE;
2195
2196    return GL_FALSE;
2197 }
2198
2199
2200 static void radeonWrapRunPipeline( struct gl_context *ctx )
2201 {
2202    r100ContextPtr rmesa = R100_CONTEXT(ctx);
2203    GLboolean has_material;
2204
2205    if (0)
2206       fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2207
2208    /* Validate state:
2209     */
2210    if (rmesa->radeon.NewGLState)
2211       if (!radeonValidateState( ctx ))
2212          FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2213
2214    has_material = (ctx->Light.Enabled && check_material( ctx ));
2215
2216    if (has_material) {
2217       TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2218    }
2219
2220    /* Run the pipeline.
2221     */
2222    _tnl_run_pipeline( ctx );
2223
2224    if (has_material) {
2225       TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2226    }
2227 }
2228
2229 static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2230 {
2231    r100ContextPtr r100 = R100_CONTEXT(ctx);
2232    GLint i;
2233
2234    radeon_firevertices(&r100->radeon);
2235
2236    RADEON_STATECHANGE(r100, stp);
2237
2238    /* Must flip pattern upside down.
2239     */
2240    for ( i = 31 ; i >= 0; i--) {
2241      r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2242    }
2243 }
2244
2245
2246 /* Initialize the driver's state functions.
2247  * Many of the ctx->Driver functions might have been initialized to
2248  * software defaults in the earlier _mesa_init_driver_functions() call.
2249  */
2250 void radeonInitStateFuncs( struct gl_context *ctx , GLboolean dri2 )
2251 {
2252    ctx->Driver.UpdateState              = radeonInvalidateState;
2253    ctx->Driver.LightingSpaceChange      = radeonLightingSpaceChange;
2254
2255    ctx->Driver.DrawBuffer               = radeonDrawBuffer;
2256    ctx->Driver.ReadBuffer               = radeonReadBuffer;
2257    ctx->Driver.CopyPixels               = _mesa_meta_CopyPixels;
2258    ctx->Driver.DrawPixels               = _mesa_meta_DrawPixels;
2259    if (dri2)
2260            ctx->Driver.ReadPixels               = radeonReadPixels;
2261
2262    ctx->Driver.AlphaFunc                = radeonAlphaFunc;
2263    ctx->Driver.BlendEquationSeparate    = radeonBlendEquationSeparate;
2264    ctx->Driver.BlendFuncSeparate        = radeonBlendFuncSeparate;
2265    ctx->Driver.ClearColor               = radeonClearColor;
2266    ctx->Driver.ClearDepth               = radeonClearDepth;
2267    ctx->Driver.ClearStencil             = radeonClearStencil;
2268    ctx->Driver.ClipPlane                = radeonClipPlane;
2269    ctx->Driver.ColorMask                = radeonColorMask;
2270    ctx->Driver.CullFace                 = radeonCullFace;
2271    ctx->Driver.DepthFunc                = radeonDepthFunc;
2272    ctx->Driver.DepthMask                = radeonDepthMask;
2273    ctx->Driver.DepthRange               = radeonDepthRange;
2274    ctx->Driver.Enable                   = radeonEnable;
2275    ctx->Driver.Fogfv                    = radeonFogfv;
2276    ctx->Driver.FrontFace                = radeonFrontFace;
2277    ctx->Driver.Hint                     = NULL;
2278    ctx->Driver.LightModelfv             = radeonLightModelfv;
2279    ctx->Driver.Lightfv                  = radeonLightfv;
2280    ctx->Driver.LineStipple              = radeonLineStipple;
2281    ctx->Driver.LineWidth                = radeonLineWidth;
2282    ctx->Driver.LogicOpcode              = radeonLogicOpCode;
2283    ctx->Driver.PolygonMode              = radeonPolygonMode;
2284    ctx->Driver.PolygonOffset            = radeonPolygonOffset;
2285    if (dri2)
2286       ctx->Driver.PolygonStipple                = radeonPolygonStipple;
2287    else
2288       ctx->Driver.PolygonStipple                = radeonPolygonStipplePreKMS;
2289    ctx->Driver.RenderMode               = radeonRenderMode;
2290    ctx->Driver.Scissor                  = radeonScissor;
2291    ctx->Driver.ShadeModel               = radeonShadeModel;
2292    ctx->Driver.StencilFuncSeparate      = radeonStencilFuncSeparate;
2293    ctx->Driver.StencilMaskSeparate      = radeonStencilMaskSeparate;
2294    ctx->Driver.StencilOpSeparate        = radeonStencilOpSeparate;
2295    ctx->Driver.Viewport                 = radeonViewport;
2296
2297    TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2298    TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2299 }