patch to import Jon Smirl's work from Bitkeeper
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_lighting.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.5 2002/09/16 18:05:20 eich Exp $ */
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 a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Gareth Hughes <gareth@valinux.com>
28 * Keith Whitwell <keith@tungstengraphics.com>
29 */
30
31 #include "glheader.h"
32 #include "imports.h"
33 #include "api_arrayelt.h"
34 /* #include "mmath.h" */
35 #include "enums.h"
36 #include "colormac.h"
37
38
39 #include "radeon_context.h"
40 #include "radeon_ioctl.h"
41 #include "radeon_state.h"
42 #include "radeon_tcl.h"
43 #include "radeon_tex.h"
44 #include "radeon_vtxfmt.h"
45
46
47
48 /* =============================================================
49 * Materials
50 */
51
52
53 /* Update on colormaterial, material emmissive/ambient,
54 * lightmodel.globalambient
55 */
56 void update_global_ambient( GLcontext *ctx )
57 {
58 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
59 float *fcmd = (float *)RADEON_DB_STATE( glt );
60
61 /* Need to do more if both emmissive & ambient are PREMULT:
62 */
63 if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
64 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
65 (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
66 {
67 COPY_3V( &fcmd[GLT_RED],
68 ctx->Light.Material[0].Emission);
69 ACC_SCALE_3V( &fcmd[GLT_RED],
70 ctx->Light.Model.Ambient,
71 ctx->Light.Material[0].Ambient);
72 }
73 else
74 {
75 COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
76 }
77
78 RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
79 }
80
81 /* Update on change to
82 * - light[p].colors
83 * - light[p].enabled
84 * - material,
85 * - colormaterial enabled
86 * - colormaterial bitmask
87 */
88 void update_light_colors( GLcontext *ctx, GLuint p )
89 {
90 struct gl_light *l = &ctx->Light.Light[p];
91
92 /* fprintf(stderr, "%s\n", __FUNCTION__); */
93
94 if (l->Enabled) {
95 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
96 float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
97 GLuint bitmask = ctx->Light.ColorMaterialBitmask;
98 struct gl_material *mat = &ctx->Light.Material[0];
99
100 COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
101 COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
102 COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
103
104 if (!ctx->Light.ColorMaterialEnabled)
105 bitmask = 0;
106
107 if ((bitmask & FRONT_AMBIENT_BIT) == 0)
108 SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat->Ambient );
109
110 if ((bitmask & FRONT_DIFFUSE_BIT) == 0)
111 SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat->Diffuse );
112
113 if ((bitmask & FRONT_SPECULAR_BIT) == 0)
114 SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat->Specular );
115
116 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
117 }
118 }
119
120 /* Also fallback for asym colormaterial mode in twoside lighting...
121 */
122 void check_twoside_fallback( GLcontext *ctx )
123 {
124 GLboolean fallback = GL_FALSE;
125
126 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
127 if (memcmp( &ctx->Light.Material[0],
128 &ctx->Light.Material[1],
129 sizeof(struct gl_material)) != 0)
130 fallback = GL_TRUE;
131 else if (ctx->Light.ColorMaterialEnabled &&
132 (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
133 ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
134 fallback = GL_TRUE;
135 }
136
137 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
138 }
139
140 void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
141 {
142 if (ctx->Light.ColorMaterialEnabled) {
143 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
144 GLuint light_model_ctl = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
145 GLuint mask = ctx->Light.ColorMaterialBitmask;
146
147 /* Default to PREMULT:
148 */
149 light_model_ctl &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
150 (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
151 (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
152 (3 << RADEON_SPECULAR_SOURCE_SHIFT));
153
154 if (mask & FRONT_EMISSION_BIT) {
155 light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
156 RADEON_EMISSIVE_SOURCE_SHIFT);
157 }
158
159 if (mask & FRONT_AMBIENT_BIT) {
160 light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
161 RADEON_AMBIENT_SOURCE_SHIFT);
162 }
163
164 if (mask & FRONT_DIFFUSE_BIT) {
165 light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
166 RADEON_DIFFUSE_SOURCE_SHIFT);
167 }
168
169 if (mask & FRONT_SPECULAR_BIT) {
170 light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
171 RADEON_SPECULAR_SOURCE_SHIFT);
172 }
173
174 if (light_model_ctl != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
175 GLuint p;
176
177 RADEON_STATECHANGE( rmesa, tcl );
178 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl;
179
180 for (p = 0 ; p < MAX_LIGHTS; p++)
181 update_light_colors( ctx, p );
182 update_global_ambient( ctx );
183 }
184 }
185
186 check_twoside_fallback( ctx );
187 }
188
189 void radeonUpdateMaterial( GLcontext *ctx )
190 {
191 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
192 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
193 GLuint p;
194 GLuint mask = ~0;
195
196 if (ctx->Light.ColorMaterialEnabled)
197 mask &= ~ctx->Light.ColorMaterialBitmask;
198
199 if (RADEON_DEBUG & DEBUG_STATE)
200 fprintf(stderr, "%s\n", __FUNCTION__);
201
202
203 if (mask & FRONT_EMISSION_BIT) {
204 fcmd[MTL_EMMISSIVE_RED] = ctx->Light.Material[0].Emission[0];
205 fcmd[MTL_EMMISSIVE_GREEN] = ctx->Light.Material[0].Emission[1];
206 fcmd[MTL_EMMISSIVE_BLUE] = ctx->Light.Material[0].Emission[2];
207 fcmd[MTL_EMMISSIVE_ALPHA] = ctx->Light.Material[0].Emission[3];
208 }
209 if (mask & FRONT_AMBIENT_BIT) {
210 fcmd[MTL_AMBIENT_RED] = ctx->Light.Material[0].Ambient[0];
211 fcmd[MTL_AMBIENT_GREEN] = ctx->Light.Material[0].Ambient[1];
212 fcmd[MTL_AMBIENT_BLUE] = ctx->Light.Material[0].Ambient[2];
213 fcmd[MTL_AMBIENT_ALPHA] = ctx->Light.Material[0].Ambient[3];
214 }
215 if (mask & FRONT_DIFFUSE_BIT) {
216 fcmd[MTL_DIFFUSE_RED] = ctx->Light.Material[0].Diffuse[0];
217 fcmd[MTL_DIFFUSE_GREEN] = ctx->Light.Material[0].Diffuse[1];
218 fcmd[MTL_DIFFUSE_BLUE] = ctx->Light.Material[0].Diffuse[2];
219 fcmd[MTL_DIFFUSE_ALPHA] = ctx->Light.Material[0].Diffuse[3];
220 }
221 if (mask & FRONT_SPECULAR_BIT) {
222 fcmd[MTL_SPECULAR_RED] = ctx->Light.Material[0].Specular[0];
223 fcmd[MTL_SPECULAR_GREEN] = ctx->Light.Material[0].Specular[1];
224 fcmd[MTL_SPECULAR_BLUE] = ctx->Light.Material[0].Specular[2];
225 fcmd[MTL_SPECULAR_ALPHA] = ctx->Light.Material[0].Specular[3];
226 }
227 if (mask & FRONT_SHININESS_BIT) {
228 fcmd[MTL_SHININESS] = ctx->Light.Material[0].Shininess;
229 }
230
231 if (RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl )) {
232 for (p = 0 ; p < MAX_LIGHTS; p++)
233 update_light_colors( ctx, p );
234
235 check_twoside_fallback( ctx );
236 update_global_ambient( ctx );
237 }
238 else if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_STATE))
239 fprintf(stderr, "%s: Elided noop material call\n", __FUNCTION__);
240 }
241
242 /* _NEW_LIGHT
243 * _NEW_MODELVIEW
244 * _MESA_NEW_NEED_EYE_COORDS
245 *
246 * Uses derived state from mesa:
247 * _VP_inf_norm
248 * _h_inf_norm
249 * _Position
250 * _NormDirection
251 * _ModelViewInvScale
252 * _NeedEyeCoords
253 * _EyeZDir
254 *
255 * which are calculated in light.c and are correct for the current
256 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
257 * and _MESA_NEW_NEED_EYE_COORDS.
258 */
259 void radeonUpdateLighting( GLcontext *ctx )
260 {
261 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
262
263 /* Have to check these, or have an automatic shortcircuit mechanism
264 * to remove noop statechanges. (Or just do a better job on the
265 * front end).
266 */
267 {
268 GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
269
270 if (ctx->_NeedEyeCoords)
271 tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
272 else
273 tmp |= RADEON_LIGHT_IN_MODELSPACE;
274
275
276 /* Leave this test disabled: (unexplained q3 lockup) (even with
277 new packets)
278 */
279 if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
280 {
281 RADEON_STATECHANGE( rmesa, tcl );
282 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
283 }
284 }
285
286 {
287 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
288 fcmd[EYE_X] = ctx->_EyeZDir[0];
289 fcmd[EYE_Y] = ctx->_EyeZDir[1];
290 fcmd[EYE_Z] = - ctx->_EyeZDir[2];
291 fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
292 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
293 }
294
295
296 /* RADEON_STATECHANGE( rmesa, glt ); */
297
298 if (ctx->Light.Enabled) {
299 GLint p;
300 for (p = 0 ; p < MAX_LIGHTS; p++) {
301 if (ctx->Light.Light[p].Enabled) {
302 struct gl_light *l = &ctx->Light.Light[p];
303 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
304
305 if (l->EyePosition[3] == 0.0) {
306 COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
307 COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
308 fcmd[LIT_POSITION_W] = 0;
309 fcmd[LIT_DIRECTION_W] = 0;
310 } else {
311 COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
312 fcmd[LIT_DIRECTION_X] = -l->_NormDirection[0];
313 fcmd[LIT_DIRECTION_Y] = -l->_NormDirection[1];
314 fcmd[LIT_DIRECTION_Z] = -l->_NormDirection[2];
315 fcmd[LIT_DIRECTION_W] = 0;
316 }
317
318 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
319 }
320 }
321 }
322 }
323
324
325 void radeonLightfv( GLcontext *ctx, GLenum light,
326 GLenum pname, const GLfloat *params )
327 {
328 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
329 GLint p = light - GL_LIGHT0;
330 struct gl_light *l = &ctx->Light.Light[p];
331 GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
332
333
334 switch (pname) {
335 case GL_AMBIENT:
336 case GL_DIFFUSE:
337 case GL_SPECULAR:
338 update_light_colors( ctx, p );
339 break;
340
341 case GL_SPOT_DIRECTION:
342 /* picked up in update_light */
343 break;
344
345 case GL_POSITION: {
346 /* positions picked up in update_light, but can do flag here */
347 GLuint flag = (p&1)? RADEON_LIGHT_1_IS_LOCAL : RADEON_LIGHT_0_IS_LOCAL;
348 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
349
350 RADEON_STATECHANGE(rmesa, tcl);
351 if (l->EyePosition[3] != 0.0F)
352 rmesa->hw.tcl.cmd[idx] |= flag;
353 else
354 rmesa->hw.tcl.cmd[idx] &= ~flag;
355 break;
356 }
357
358 case GL_SPOT_EXPONENT:
359 RADEON_STATECHANGE(rmesa, lit[p]);
360 fcmd[LIT_SPOT_EXPONENT] = params[0];
361 break;
362
363 case GL_SPOT_CUTOFF: {
364 GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
365 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
366
367 RADEON_STATECHANGE(rmesa, lit[p]);
368 fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
369
370 RADEON_STATECHANGE(rmesa, tcl);
371 if (l->SpotCutoff != 180.0F)
372 rmesa->hw.tcl.cmd[idx] |= flag;
373 else
374 rmesa->hw.tcl.cmd[idx] &= ~flag;
375 break;
376 }
377
378 case GL_CONSTANT_ATTENUATION:
379 RADEON_STATECHANGE(rmesa, lit[p]);
380 fcmd[LIT_ATTEN_CONST] = params[0];
381 break;
382 case GL_LINEAR_ATTENUATION:
383 RADEON_STATECHANGE(rmesa, lit[p]);
384 fcmd[LIT_ATTEN_LINEAR] = params[0];
385 break;
386 case GL_QUADRATIC_ATTENUATION:
387 RADEON_STATECHANGE(rmesa, lit[p]);
388 fcmd[LIT_ATTEN_QUADRATIC] = params[0];
389 break;
390 default:
391 return;
392 }
393
394 }
395
396
397
398
399 void radeonLightModelfv( GLcontext *ctx, GLenum pname,
400 const GLfloat *param )
401 {
402 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
403
404 switch (pname) {
405 case GL_LIGHT_MODEL_AMBIENT:
406 update_global_ambient( ctx );
407 break;
408
409 case GL_LIGHT_MODEL_LOCAL_VIEWER:
410 RADEON_STATECHANGE( rmesa, tcl );
411 if (ctx->Light.Model.LocalViewer)
412 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
413 else
414 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
415 break;
416
417 case GL_LIGHT_MODEL_TWO_SIDE:
418 RADEON_STATECHANGE( rmesa, tcl );
419 if (ctx->Light.Model.TwoSide)
420 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
421 else
422 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
423
424 check_twoside_fallback( ctx );
425
426 #if _HAVE_SWTNL
427 if (rmesa->TclFallback) {
428 radeonChooseRenderState( ctx );
429 radeonChooseVertexState( ctx );
430 }
431 #endif
432 break;
433
434 case GL_LIGHT_MODEL_COLOR_CONTROL:
435 radeonUpdateSpecular(ctx);
436
437 RADEON_STATECHANGE( rmesa, tcl );
438 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
439 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
440 ~RADEON_DIFFUSE_SPECULAR_COMBINE;
441 else
442 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=
443 RADEON_DIFFUSE_SPECULAR_COMBINE;
444 break;
445
446 default:
447 break;
448 }
449 }
450
451
452 /* =============================================================
453 * Fog
454 */
455
456
457 static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
458 {
459 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
460 union { int i; float f; } c, d;
461 GLchan col[4];
462
463 c.i = rmesa->hw.fog.cmd[FOG_C];
464 d.i = rmesa->hw.fog.cmd[FOG_D];
465
466 switch (pname) {
467 case GL_FOG_MODE:
468 if (!ctx->Fog.Enabled)
469 return;
470 RADEON_STATECHANGE(rmesa, tcl);
471 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
472 switch (ctx->Fog.Mode) {
473 case GL_LINEAR:
474 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
475 if (ctx->Fog.Start == ctx->Fog.End) {
476 c.f = 1.0F;
477 d.f = 1.0F;
478 }
479 else {
480 c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
481 d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
482 }
483 break;
484 case GL_EXP:
485 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
486 c.f = 0.0;
487 d.f = ctx->Fog.Density;
488 break;
489 case GL_EXP2:
490 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
491 c.f = 0.0;
492 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
493 break;
494 default:
495 return;
496 }
497 break;
498 case GL_FOG_DENSITY:
499 switch (ctx->Fog.Mode) {
500 case GL_EXP:
501 c.f = 0.0;
502 d.f = ctx->Fog.Density;
503 break;
504 case GL_EXP2:
505 c.f = 0.0;
506 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
507 break;
508 default:
509 break;
510 }
511 break;
512 case GL_FOG_START:
513 case GL_FOG_END:
514 if (ctx->Fog.Mode == GL_LINEAR) {
515 if (ctx->Fog.Start == ctx->Fog.End) {
516 c.f = 1.0F;
517 d.f = 1.0F;
518 } else {
519 c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
520 d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
521 }
522 }
523 break;
524 case GL_FOG_COLOR:
525 RADEON_STATECHANGE( rmesa, ctx );
526 UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
527 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] =
528 radeonPackColor( 4, col[0], col[1], col[2], 0 );
529 break;
530 case GL_FOG_COORDINATE_SOURCE_EXT:
531 /* What to do?
532 */
533 break;
534 default:
535 return;
536 }
537
538 if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
539 RADEON_STATECHANGE( rmesa, fog );
540 rmesa->hw.fog.cmd[FOG_C] = c.i;
541 rmesa->hw.fog.cmd[FOG_D] = d.i;
542 }
543 }
544
545 /* Examine lighting and texture state to determine if separate specular
546 * should be enabled.
547 */
548 void radeonUpdateSpecular( GLcontext *ctx )
549 {
550 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
551 GLuint p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
552
553 if ( ctx->_TriangleCaps & DD_SEPARATE_SPECULAR ) {
554 p |= RADEON_SPECULAR_ENABLE;
555 } else {
556 p &= ~RADEON_SPECULAR_ENABLE;
557 }
558
559 if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
560 RADEON_STATECHANGE( rmesa, ctx );
561 rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
562 }
563
564 /* Bizzare: have to leave lighting enabled to get fog.
565 */
566 RADEON_STATECHANGE( rmesa, tcl );
567 if ((ctx->Light.Enabled &&
568 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
569 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
570 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
571 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
572 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
573 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
574 }
575 else if (ctx->Fog.Enabled) {
576 if (ctx->Light.Enabled) {
577 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
578 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
579 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
580 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
581 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
582 } else {
583 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
584 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
585 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
586 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
587 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
588 }
589 }
590 else if (ctx->Light.Enabled) {
591 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
592 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
593 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
594 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
595 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
596 } else if (ctx->Fog.ColorSumEnabled ) {
597 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
598 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
599 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
600 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
601 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
602 } else {
603 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
604 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
605 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
606 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
607 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
608 }
609
610 #if _HAVE_SWTNL
611 /* Update vertex/render formats
612 */
613 if (rmesa->TclFallback) {
614 radeonChooseRenderState( ctx );
615 radeonChooseVertexState( ctx );
616 }
617 #endif
618 }
619
620
621
622 static void radeonLightingSpaceChange( GLcontext *ctx )
623 {
624 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
625 GLboolean tmp;
626 RADEON_STATECHANGE( rmesa, tcl );
627
628 if (RADEON_DEBUG & DEBUG_STATE)
629 fprintf(stderr, "%s %d\n", __FUNCTION__, ctx->_NeedEyeCoords);
630
631 if (ctx->_NeedEyeCoords)
632 tmp = ctx->Transform.RescaleNormals;
633 else
634 tmp = !ctx->Transform.RescaleNormals;
635
636 if ( tmp ) {
637 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
638 } else {
639 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
640 }
641 }
642
643 void radeonInitLightStateFuncs( GLcontext *ctx )
644 {
645 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
646 int i;
647
648 ctx->Driver.LightModelfv = radeonLightModelfv;
649 ctx->Driver.Lightfv = radeonLightfv;
650 ctx->Driver.Fogfv = radeonFogfv;
651 ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
652
653 for (i = 0 ; i < 8; i++) {
654 struct gl_light *l = &ctx->Light.Light[i];
655 GLenum p = GL_LIGHT0 + i;
656 *(float *)&(rmesa->hw.lit[i].cmd[LIT_RANGE_CUTOFF]) = FLT_MAX;
657
658 ctx->Driver.Lightfv( ctx, p, GL_AMBIENT, l->Ambient );
659 ctx->Driver.Lightfv( ctx, p, GL_DIFFUSE, l->Diffuse );
660 ctx->Driver.Lightfv( ctx, p, GL_SPECULAR, l->Specular );
661 ctx->Driver.Lightfv( ctx, p, GL_POSITION, 0 );
662 ctx->Driver.Lightfv( ctx, p, GL_SPOT_DIRECTION, 0 );
663 ctx->Driver.Lightfv( ctx, p, GL_SPOT_EXPONENT, &l->SpotExponent );
664 ctx->Driver.Lightfv( ctx, p, GL_SPOT_CUTOFF, &l->SpotCutoff );
665 ctx->Driver.Lightfv( ctx, p, GL_CONSTANT_ATTENUATION,
666 &l->ConstantAttenuation );
667 ctx->Driver.Lightfv( ctx, p, GL_LINEAR_ATTENUATION,
668 &l->LinearAttenuation );
669 ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION,
670 &l->QuadraticAttenuation );
671 }
672
673 ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT,
674 ctx->Light.Model.Ambient );
675
676 ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
677 ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
678 ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
679 ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
680 ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
681 ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, 0 );
682 }