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