Mesa (master): r300/compiler: Standardize the number of bits used by swizzle fields

Tom Stellard tstellar at kemper.freedesktop.org
Sun Jan 30 05:37:21 UTC 2011


Module: Mesa
Branch: master
Commit: 8f32c6cfc6503dd234f09fb06941803866c23c65
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8f32c6cfc6503dd234f09fb06941803866c23c65

Author: Tom Stellard <tstellar at gmail.com>
Date:   Sat Jan 29 14:37:58 2011 -0800

r300/compiler: Standardize the number of bits used by swizzle fields

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.

---

 .../dri/r300/compiler/r300_fragprog_swizzle.c      |    9 +++---
 .../drivers/dri/r300/compiler/r500_fragprog_emit.c |    2 +-
 .../dri/r300/compiler/radeon_compiler_util.c       |   28 +++++++++++++++++--
 .../dri/r300/compiler/radeon_compiler_util.h       |    4 ++-
 .../drivers/dri/r300/compiler/radeon_dataflow.c    |   10 +-----
 .../dri/r300/compiler/radeon_pair_schedule.c       |   11 ++++---
 .../dri/r300/compiler/radeon_pair_translate.c      |    6 +++-
 .../dri/r300/compiler/radeon_program_pair.c        |   22 +--------------
 .../dri/r300/compiler/radeon_program_pair.h        |    2 +-
 .../dri/r300/compiler/radeon_program_print.c       |    2 +-
 10 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
index 05d3da8..fa906f2 100644
--- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
@@ -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;
diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
index 5da82d9..1febc19 100644
--- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
+++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
@@ -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;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c
index 2482fc6..15ec441 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c
@@ -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);
 		}
 	}
 
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h
index 461ab9f..dd0f6c6 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h
@@ -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);
 
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
index d0a64d9..c080d5a 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
@@ -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;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
index 9beb5d6..dd26049 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
@@ -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;
 			}
 		}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
index ddc676c..6d7263b 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
@@ -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);
 		}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
index 5905d26..6887479 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
@@ -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];
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
index ccf7a00..6708b16 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
@@ -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;
 };
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c
index 193844e..390d131 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c
@@ -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");
 	}




More information about the mesa-commit mailing list