Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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