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