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