mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
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.
This commit is contained in:
parent
debc45bca0
commit
8f32c6cfc6
10 changed files with 49 additions and 45 deletions
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue