Track Radeon driver symlinks in Git.
[mesa.git] / src / mesa / drivers / dri / r300 / r300_fragprog_swizzle.c
index a86d2bd47128e1c2b3528a2b2cabb547b74203be..fc9d855bce6ab7e2f4c7faa0b0bb47eb13fed93f 100644 (file)
@@ -92,7 +92,7 @@ static const struct swizzle_data* lookup_native_swizzle(GLuint swizzle)
 GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg)
 {
        if (reg.Abs)
-               reg.NegateBase = 0;
+               reg.Negate = NEGATE_NONE;
 
        if (opcode == OPCODE_KIL ||
            opcode == OPCODE_TEX ||
@@ -100,7 +100,7 @@ GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg)
            opcode == OPCODE_TXP) {
                int j;
 
-               if (reg.Abs || reg.NegateBase != (15*reg.NegateAbs))
+               if (reg.Abs || reg.Negate)
                        return GL_FALSE;
 
                for(j = 0; j < 4; ++j) {
@@ -121,7 +121,7 @@ GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg)
                if (GET_SWZ(reg.Swizzle, j) != SWIZZLE_NIL)
                        relevant |= 1 << j;
 
-       if ((reg.NegateBase & relevant) && (reg.NegateBase & relevant) != relevant)
+       if ((reg.Negate & relevant) && ((reg.Negate & relevant) != relevant))
                return GL_FALSE;
 
        if (!lookup_native_swizzle(reg.Swizzle))
@@ -137,13 +137,12 @@ GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg)
 void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src)
 {
        if (src.Abs)
-               src.NegateBase = 0;
+               src.Negate = NEGATE_NONE;
 
        while(dst.WriteMask) {
                const struct swizzle_data *best_swizzle = 0;
                GLuint best_matchcount = 0;
                GLuint best_matchmask = 0;
-               GLboolean rgbnegate;
                int i, comp;
 
                for(i = 0; i < num_native_swizzles; ++i) {
@@ -157,6 +156,11 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst,
                                if (swz == SWIZZLE_NIL)
                                        continue;
                                if (swz == GET_SWZ(sd->hash, comp)) {
+                                       /* check if the negate bit of current component
+                                        * is the same for already matched components */
+                                       if (matchmask && (!!(src.Negate & matchmask) != !!(src.Negate & (1 << comp))))
+                                               continue;
+
                                        matchcount++;
                                        matchmask |= 1 << comp;
                                }
@@ -170,13 +174,6 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst,
                        }
                }
 
-               if ((src.NegateBase & best_matchmask) != 0) {
-                       best_matchmask &= src.NegateBase;
-                       rgbnegate = !src.NegateAbs;
-               } else {
-                       rgbnegate = src.NegateAbs;
-               }
-
                struct prog_instruction *inst;
 
                _mesa_insert_instructions(s->Program, s->IP, 1);
@@ -185,6 +182,7 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst,
                inst->DstReg = dst;
                inst->DstReg.WriteMask &= (best_matchmask | WRITEMASK_W);
                inst->SrcReg[0] = src;
+               inst->SrcReg[0].Negate = (best_matchmask & src.Negate) ? NEGATE_XYZW : NEGATE_NONE;
                /* Note: We rely on NqSSA/DCE to set unused swizzle components to NIL */
 
                dst.WriteMask &= ~inst->DstReg.WriteMask;