diff options
author | Brian Paul <[email protected]> | 2011-07-27 09:13:32 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2011-09-23 07:58:48 -0600 |
commit | 2b2a69e088416a18e3bb119ea1edb594b06e06fe (patch) | |
tree | 9358f89c831e08c2653c7db79822ad143cb9ab01 /src/gallium | |
parent | 7d09df0cbc7e4524919a025cdd506b29e2d8b4f1 (diff) |
svga: test register W component in emit_kil()
Only the XYZ components are checked to be negative by SVGA3DOP_TEXKILL.
GL_ARB_fp requires all four components be checked. Emit a second texkill
for W if needed.
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/svga/svga_tgsi_insn.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c index 91fd470eabc..c528e698ccb 100644 --- a/src/gallium/drivers/svga/svga_tgsi_insn.c +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c @@ -1225,28 +1225,56 @@ static boolean emit_sub(struct svga_shader_emitter *emit, static boolean emit_kil(struct svga_shader_emitter *emit, const struct tgsi_full_instruction *insn ) { - SVGA3dShaderInstToken inst; const struct tgsi_full_src_register *reg = &insn->Src[0]; - struct src_register src0; + struct src_register src0, srcIn; + /* is the W component tested in another position? */ + const boolean w_tested = (reg->Register.SwizzleW == reg->Register.SwizzleX || + reg->Register.SwizzleW == reg->Register.SwizzleY || + reg->Register.SwizzleW == reg->Register.SwizzleZ); + const boolean special = (reg->Register.Absolute || + reg->Register.Negate || + reg->Register.Indirect || + reg->Register.SwizzleX != 0 || + reg->Register.SwizzleY != 1 || + reg->Register.SwizzleZ != 2 || + reg->Register.File != TGSI_FILE_TEMPORARY); + SVGA3dShaderDestToken temp; - inst = inst_token( SVGA3DOP_TEXKILL ); - src0 = translate_src_register( emit, reg ); - - if (reg->Register.Absolute || - reg->Register.Negate || - reg->Register.Indirect || - reg->Register.SwizzleX != 0 || - reg->Register.SwizzleY != 1 || - reg->Register.SwizzleZ != 2 || - reg->Register.File != TGSI_FILE_TEMPORARY) - { - SVGA3dShaderDestToken temp = get_temp( emit ); + src0 = srcIn = translate_src_register( emit, reg ); + + if (special || !w_tested) { + /* need a temp reg */ + temp = get_temp( emit ); + } + + if (special) { + /* move the source into a temp register */ + submit_op1( emit, inst_token( SVGA3DOP_MOV ), + writemask( temp, TGSI_WRITEMASK_XYZ ), + src0 ); - submit_op1( emit, inst_token( SVGA3DOP_MOV ), temp, src0 ); src0 = src( temp ); } - return submit_op0( emit, inst, dst(src0) ); + /* do the texkill (on the xyz components) */ + if (!submit_op0( emit, inst_token( SVGA3DOP_TEXKILL ), dst(src0) )) + return FALSE; + + if (!w_tested) { + /* need to emit a second texkill to test the W component */ + /* put src.wwww into temp register */ + if (!submit_op1(emit, + inst_token( SVGA3DOP_MOV ), + writemask( temp, TGSI_WRITEMASK_XYZ ), + scalar(srcIn, TGSI_SWIZZLE_W))) + return FALSE; + + /* second texkill */ + if (!submit_op0( emit, inst_token( SVGA3DOP_TEXKILL ), temp )) + return FALSE; + } + + return TRUE; } |