Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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