svga: Don't emit zero writemasks.

This fixes a regression with Lightsmark, where more compact TGSI from Mesa
was causing a zero mask MOV to be emitted for shadow map compare, causing
problems in some backends.

Add a few more assertions to catch cases like this.
This commit is contained in:
José Fonseca 2010-02-22 18:01:32 +00:00
parent 9bef69782d
commit 46d8ca023d
2 changed files with 38 additions and 27 deletions

View file

@ -138,6 +138,7 @@ static INLINE boolean emit_dst( struct svga_shader_emitter *emit,
SVGA3dShaderDestToken dest )
{
assert(dest.reserved0);
assert(dest.mask);
return svga_shader_emit_dword( emit, dest.value );
}
@ -267,6 +268,7 @@ static INLINE SVGA3dShaderDestToken
writemask( SVGA3dShaderDestToken dest,
unsigned mask )
{
assert(dest.mask & mask);
dest.mask &= mask;
return dest;
}

View file

@ -112,6 +112,7 @@ translate_dst_register( struct svga_shader_emitter *emit,
}
dest.mask = reg->DstRegister.WriteMask;
assert(dest.mask);
if (insn->Instruction.Saturate)
dest.dstMod = SVGA3DDSTMOD_SATURATE;
@ -1409,34 +1410,42 @@ static boolean emit_tex(struct svga_shader_emitter *emit,
if (compare) {
SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
struct src_register one =
scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
if (dst.mask & TGSI_WRITEMASK_XYZ) {
SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
/* Divide texcoord R by Q */
if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
src0_zdivw,
scalar(src0, TGSI_SWIZZLE_W) ))
return FALSE;
/* Divide texcoord R by Q */
if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
src0_zdivw,
scalar(src0, TGSI_SWIZZLE_W) ))
return FALSE;
if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
src0_zdivw,
scalar(src0, TGSI_SWIZZLE_Z),
src(src0_zdivw) ))
return FALSE;
if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
src0_zdivw,
scalar(src0, TGSI_SWIZZLE_Z),
src(src0_zdivw) ))
return FALSE;
if (!emit_select(
emit,
emit->key.fkey.tex[src1.base.num].compare_func,
dst,
src(src0_zdivw),
tex_src_x))
return FALSE;
if (!emit_select(
emit,
emit->key.fkey.tex[src1.base.num].compare_func,
writemask( dst, TGSI_WRITEMASK_XYZ ),
src(src0_zdivw),
tex_src_x))
return FALSE;
}
return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
writemask( dst, TGSI_WRITEMASK_W),
one );
if (dst.mask & TGSI_WRITEMASK_W) {
struct src_register one =
scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
writemask( dst, TGSI_WRITEMASK_W ),
one ))
return FALSE;
}
return TRUE;
}
else if (!emit->use_sm30 && dst.mask != TGSI_WRITEMASK_XYZW)
{
@ -1824,13 +1833,13 @@ static boolean emit_exp(struct svga_shader_emitter *emit,
*/
if (dst.mask & TGSI_WRITEMASK_X) {
if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
writemask( dst, TGSI_WRITEMASK_X ),
src0,
scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) )
return FALSE;
if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
writemask( dst, TGSI_WRITEMASK_X ),
scalar( src( dst ), TGSI_SWIZZLE_X ) ) )
return FALSE;
@ -1842,7 +1851,7 @@ static boolean emit_exp(struct svga_shader_emitter *emit,
*/
if (dst.mask & TGSI_WRITEMASK_Z) {
if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ),
writemask( dst, dst.mask & TGSI_WRITEMASK_Z ),
writemask( dst, TGSI_WRITEMASK_Z ),
src0 ) )
return FALSE;
}