From 2b2a69e088416a18e3bb119ea1edb594b06e06fe Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 27 Jul 2011 09:13:32 -0600 Subject: [PATCH] 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. --- src/gallium/drivers/svga/svga_tgsi_insn.c | 60 +++++++++++++++++------ 1 file 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; } -- 2.30.2