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.tags/android-x86-2.2-r2
@@ -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; |
@@ -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; |
@@ -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); | |||
} | |||
} | |||
@@ -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); | |||
@@ -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; |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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]; |
@@ -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; | |||
}; |
@@ -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"); | |||
} |