summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2011-07-27 09:13:32 -0600
committerBrian Paul <[email protected]>2011-09-23 07:58:48 -0600
commit2b2a69e088416a18e3bb119ea1edb594b06e06fe (patch)
tree9358f89c831e08c2653c7db79822ad143cb9ab01 /src/gallium/drivers
parent7d09df0cbc7e4524919a025cdd506b29e2d8b4f1 (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/drivers')
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_insn.c60
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;
}