r300/compiler: Standardize the number of bits used by swizzle fields
authorTom Stellard <tstellar@gmail.com>
Sat, 29 Jan 2011 22:37:58 +0000 (14:37 -0800)
committerTom Stellard <tstellar@gmail.com>
Sun, 30 Jan 2011 05:32:02 +0000 (21:32 -0800)
Swizzles are now defined everywhere as a field with 12 bits that contains
4 channels worth of meaningful information.  Any channel that is unused is
set to RC_SWIZZLE_UNUSED.  This change is necessary because rgb instructions
and alpha instructions were initializing channels that would never be used
(channel 3 for rgb and channels 1-3 for alpha) with 0 (aka RC_SWIZZLE_X).
This made it impossible to use generic helper functions for swizzles,
because sometimes a channel value of 0 meant unused and other times it
meant RC_SWIZZLE_X.

All hacks that tried to guess how many channels were relevant have
also been removed.

src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h
src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
src/mesa/drivers/dri/r300/compiler/radeon_program_print.c

index 05d3da8a10d2e018eef0ea970b92be49f18c4161..fa906f2fddef94647fb13ca3bdd262ee029d1829 100644 (file)
@@ -222,13 +222,14 @@ unsigned int r300FPTranslateRGBSwizzle(unsigned int src, unsigned int swizzle)
  */
 unsigned int r300FPTranslateAlphaSwizzle(unsigned int src, unsigned int swizzle)
 {
+       unsigned int swz = GET_SWZ(swizzle, 0);
        if (src == RC_PAIR_PRESUB_SRC) {
-               return R300_ALU_ARGA_SRCP_X + swizzle;
+               return R300_ALU_ARGA_SRCP_X + swz;
        }
-       if (swizzle < 3)
-               return swizzle + 3*src;
+       if (swz < 3)
+               return swz + 3*src;
 
-       switch(swizzle) {
+       switch(swz) {
        case RC_SWIZZLE_W: return R300_ALU_ARGA_SRC0A + src;
        case RC_SWIZZLE_ONE: return R300_ALU_ARGA_ONE;
        case RC_SWIZZLE_ZERO: return R300_ALU_ARGA_ZERO;
index 5da82d90f6716a117a092af86ed1b3a49d32452f..1febc19cc2d0ff7533ba92d0d771abfcae1bbeca 100644 (file)
@@ -170,7 +170,7 @@ static unsigned int translate_arg_rgb(struct rc_pair_instruction *inst, int arg)
 static unsigned int translate_arg_alpha(struct rc_pair_instruction *inst, int i)
 {
        unsigned int t = inst->Alpha.Arg[i].Source;
-       t |= fix_hw_swizzle(inst->Alpha.Arg[i].Swizzle) << 2;
+       t |= fix_hw_swizzle(GET_SWZ(inst->Alpha.Arg[i].Swizzle, 0)) << 2;
        t |= inst->Alpha.Arg[i].Negate << 5;
        t |= inst->Alpha.Arg[i].Abs << 6;
        return t;
index 2482fc68bebf9bd92c4d0e289d6535c864d3af10..15ec4418cb87594f0a628ad557afc17f3527cf5b 100644 (file)
@@ -55,6 +55,24 @@ rc_swizzle get_swz(unsigned int swz, rc_swizzle idx)
        return GET_SWZ(swz, idx);
 }
 
+/**
+ * The purpose of this function is to standardize the number channels used by
+ * swizzles.  All swizzles regardless of what instruction they are a part of
+ * should have 4 channels initialized with values.
+ * @param channels The number of channels in initial_value that have a
+ * meaningful value.
+ * @return An initialized swizzle that has all of the unused channels set to
+ * RC_SWIZZLE_UNUSED.
+ */
+unsigned int rc_init_swizzle(unsigned int initial_value, unsigned int channels)
+{
+       unsigned int i;
+       for (i = channels; i < 4; i++) {
+               SET_SWZ(initial_value, i, RC_SWIZZLE_UNUSED);
+       }
+       return initial_value;
+}
+
 unsigned int combine_swizzles4(unsigned int src,
                rc_swizzle swz_x, rc_swizzle swz_y, rc_swizzle swz_z, rc_swizzle swz_w)
 {
@@ -147,13 +165,17 @@ unsigned int rc_src_reads_dst_mask(
        return dst_mask & rc_swizzle_to_writemask(src_swz);
 }
 
-unsigned int rc_source_type_swz(unsigned int swizzle, unsigned int channels)
+/**
+ * @return A bit mask specifying whether this swizzle will select from an RGB
+ * source, an Alpha source, or both.
+ */
+unsigned int rc_source_type_swz(unsigned int swizzle)
 {
        unsigned int chan;
        unsigned int swz = RC_SWIZZLE_UNUSED;
        unsigned int ret = RC_SOURCE_NONE;
 
-       for(chan = 0; chan < channels; chan++) {
+       for(chan = 0; chan < 4; chan++) {
                swz = GET_SWZ(swizzle, chan);
                if (swz == RC_SWIZZLE_W) {
                        ret |= RC_SOURCE_ALPHA;
@@ -202,7 +224,7 @@ static void can_use_presub_read_cb(
                if (d->RemoveSrcs[i].File == file
                    && d->RemoveSrcs[i].Index == index) {
                        src_type &=
-                               ~rc_source_type_swz(d->RemoveSrcs[i].Swizzle, 4);
+                               ~rc_source_type_swz(d->RemoveSrcs[i].Swizzle);
                }
        }
 
index 461ab9ffb10676484bfe5870ddd4ee4072475468..dd0f6c66156ce7e5d69e73344ac2aacc60625be8 100644 (file)
@@ -10,6 +10,8 @@ unsigned int rc_swizzle_to_writemask(unsigned int swz);
 
 rc_swizzle get_swz(unsigned int swz, rc_swizzle idx);
 
+unsigned int rc_init_swizzle(unsigned int initial_value, unsigned int channels);
+
 unsigned int combine_swizzles4(unsigned int src,
                               rc_swizzle swz_x, rc_swizzle swz_y,
                               rc_swizzle swz_z, rc_swizzle swz_w);
@@ -32,7 +34,7 @@ unsigned int rc_src_reads_dst_mask(
                unsigned int dst_idx,
                unsigned int dst_mask);
 
-unsigned int rc_source_type_swz(unsigned int swizzle, unsigned int channels);
+unsigned int rc_source_type_swz(unsigned int swizzle);
 
 unsigned int rc_source_type_mask(unsigned int mask);
 
index d0a64d936e055fdab01db8fa3e0b0fead73b6172..c080d5aecc6eb9c99fad7cd34f8aa6632309d0f0 100644 (file)
@@ -140,14 +140,8 @@ static void pair_sub_for_all_args(
 
        for(i = 0; i < info->NumSrcRegs; i++) {
                unsigned int src_type;
-               unsigned int channels = 0;
-               if (&fullinst->U.P.RGB == sub)
-                       channels = 3;
-               else if (&fullinst->U.P.Alpha == sub)
-                       channels = 1;
-
-               assert(channels > 0);
-               src_type = rc_source_type_swz(sub->Arg[i].Swizzle, channels);
+
+               src_type = rc_source_type_swz(sub->Arg[i].Swizzle);
 
                if (src_type == RC_SOURCE_NONE)
                        continue;
index 9beb5d6357996c9651796742c6e3fba6ea55ecdb..dd26049dce969bdf65bd70edcc7839d016b901d4 100644 (file)
@@ -365,8 +365,8 @@ static int merge_presub_sources(
                for(arg = 0; arg < info->NumSrcRegs; arg++) {
                        /*If this arg does not read from an rgb source,
                         * do nothing. */
-                       if (!(rc_source_type_swz(dst_full->RGB.Arg[arg].Swizzle,
-                                                               3) & type)) {
+                       if (!(rc_source_type_swz(dst_full->RGB.Arg[arg].Swizzle)
+                                                               & type)) {
                                continue;
                        }
 
@@ -423,11 +423,11 @@ static int destructive_merge_instructions(
                unsigned int index = 0;
                int source;
 
-               if (alpha->Alpha.Arg[arg].Swizzle < 3) {
+               if (GET_SWZ(alpha->Alpha.Arg[arg].Swizzle, 0) < 3) {
                        srcrgb = 1;
                        file = alpha->RGB.Src[oldsrc].File;
                        index = alpha->RGB.Src[oldsrc].Index;
-               } else if (alpha->Alpha.Arg[arg].Swizzle < 4) {
+               } else if (GET_SWZ(alpha->Alpha.Arg[arg].Swizzle, 0) < 4) {
                        srcalpha = 1;
                        file = alpha->Alpha.Src[oldsrc].File;
                        index = alpha->Alpha.Src[oldsrc].Index;
@@ -728,7 +728,8 @@ static int convert_rgb_to_alpha(
                for (j = 0; j < 3; j++) {
                        unsigned int swz = get_swz(pair_inst->Alpha.Arg[i].Swizzle, j);
                        if (swz != RC_SWIZZLE_UNUSED) {
-                               pair_inst->Alpha.Arg[i].Swizzle = swz;
+                               pair_inst->Alpha.Arg[i].Swizzle =
+                                                       rc_init_swizzle(swz, 1);
                                break;
                        }
                }
index ddc676c9ac63dca9702f692d0a7e75bfe12610d3..6d7263b4ab62402b57170dde2aa656a34371d144 100644 (file)
@@ -28,6 +28,7 @@
 #include "radeon_program_pair.h"
 
 #include "radeon_compiler.h"
+#include "radeon_compiler_util.h"
 
 
 /**
@@ -232,7 +233,8 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c,
                                return;
                        }
                        pair->RGB.Arg[i].Source = source;
-                       pair->RGB.Arg[i].Swizzle = inst->SrcReg[i].Swizzle & 0x1ff;
+                       pair->RGB.Arg[i].Swizzle =
+                               rc_init_swizzle(inst->SrcReg[i].Swizzle, 3);
                        pair->RGB.Arg[i].Abs = inst->SrcReg[i].Abs;
                        pair->RGB.Arg[i].Negate = !!(inst->SrcReg[i].Negate & (RC_MASK_X | RC_MASK_Y | RC_MASK_Z));
                }
@@ -252,7 +254,7 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c,
                                return;
                        }
                        pair->Alpha.Arg[i].Source = source;
-                       pair->Alpha.Arg[i].Swizzle = swz;
+                       pair->Alpha.Arg[i].Swizzle = rc_init_swizzle(swz, 1);
                        pair->Alpha.Arg[i].Abs = inst->SrcReg[i].Abs;
                        pair->Alpha.Arg[i].Negate = !!(inst->SrcReg[i].Negate & RC_MASK_W);
                }
index 5905d26e521b087550dd1b8fe32d01037a17ffc4..68874795b8ac1a94ab9fb64a11e88366731d9089 100644 (file)
@@ -211,27 +211,9 @@ struct rc_pair_instruction_source * rc_pair_get_src(
        struct rc_pair_instruction * pair_inst,
        struct rc_pair_instruction_arg * arg)
 {
-       unsigned int i, type;
-       unsigned int channels = 0;
+       unsigned int type;
 
-       for(i = 0; i < 3; i++) {
-               if (arg == pair_inst->RGB.Arg + i) {
-                       channels = 3;
-                       break;
-               }
-       }
-
-       if (channels == 0) {
-               for (i = 0; i < 3; i++) {
-                       if (arg == pair_inst->Alpha.Arg + i) {
-                               channels = 1;
-                               break;
-                       }
-               }
-       }
-
-       assert(channels > 0);
-       type = rc_source_type_swz(arg->Swizzle, channels);
+       type = rc_source_type_swz(arg->Swizzle);
 
        if (type & RC_SOURCE_RGB) {
                return &pair_inst->RGB.Src[arg->Source];
index ccf7a0070cdae07ebd7e6f845216e5c257c9a49f..6708b16d29a560b63577f1c0fe67e2f6672d3d4d 100644 (file)
@@ -63,7 +63,7 @@ struct rc_pair_instruction_source {
 
 struct rc_pair_instruction_arg {
        unsigned int Source:2;
-       unsigned int Swizzle:9;
+       unsigned int Swizzle:12;
        unsigned int Abs:1;
        unsigned int Negate:1;
 };
index 193844e303bf5d6d364887a2e1e0da4725815bbf..390d1319460beb2a51a232df77c905150fabd01c 100644 (file)
@@ -379,7 +379,7 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst
                        else
                                fprintf(f,"%d", inst->Alpha.Arg[arg].Source);
                        fprintf(f,".%c%s",
-                               rc_swizzle_char(inst->Alpha.Arg[arg].Swizzle), abs);
+                               rc_swizzle_char(GET_SWZ(inst->Alpha.Arg[arg].Swizzle, 0)), abs);
                }
                fprintf(f, "\n");
        }