mesa: fix bug in GPU codegen for fixed-function two-sided lighting
The 'dots' register wasn't getting properly un-negated and un-swizzled after emitting the code for back-face lighting. So, if more than one light source was enabled, the specular exponent for the next light source was wrong. During execution we were evaluating pow(x, y) where y was negative instead of positive. This led to the outcome being zero or NaN. This fixes the occasional black triangles seen in isosurf when hacked to enable two-sided lighting.
This commit is contained in:
parent
ef6f1027ff
commit
919f57078b
|
@ -1108,6 +1108,9 @@ static void build_lighting( struct tnl_program *p )
|
||||||
|
|
||||||
if (twoside) {
|
if (twoside) {
|
||||||
if (!p->state->material_shininess_is_zero) {
|
if (!p->state->material_shininess_is_zero) {
|
||||||
|
/* Note that we negate the back-face specular exponent here.
|
||||||
|
* The negation will be un-done later in the back-face code below.
|
||||||
|
*/
|
||||||
struct ureg shininess = get_material(p, 1, STATE_SHININESS);
|
struct ureg shininess = get_material(p, 1, STATE_SHININESS);
|
||||||
emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z,
|
emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z,
|
||||||
negate(swizzle1(shininess,X)));
|
negate(swizzle1(shininess,X)));
|
||||||
|
@ -1316,6 +1319,11 @@ static void build_lighting( struct tnl_program *p )
|
||||||
mask1 = 0;
|
mask1 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For the back face we need to negate the X and Y component
|
||||||
|
* dot products. dots.Z has the negated back-face specular
|
||||||
|
* exponent. We swizzle that into the W position. This
|
||||||
|
* negation makes the back-face specular term positive again.
|
||||||
|
*/
|
||||||
dots = negate(swizzle(dots,X,Y,W,Z));
|
dots = negate(swizzle(dots,X,Y,W,Z));
|
||||||
|
|
||||||
if (!is_undef(att)) {
|
if (!is_undef(att)) {
|
||||||
|
@ -1334,8 +1342,10 @@ static void build_lighting( struct tnl_program *p )
|
||||||
|
|
||||||
emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0);
|
emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0);
|
||||||
emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1);
|
emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1);
|
||||||
/* restore negate flag for next lighting */
|
/* restore dots to its original state for subsequent lights
|
||||||
dots = negate(dots);
|
* by negating and swizzling again.
|
||||||
|
*/
|
||||||
|
dots = negate(swizzle(dots,X,Y,W,Z));
|
||||||
|
|
||||||
release_temp(p, ambient);
|
release_temp(p, ambient);
|
||||||
release_temp(p, diffuse);
|
release_temp(p, diffuse);
|
||||||
|
|
Loading…
Reference in New Issue