Procházet zdrojové kódy

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.
tags/android-x86-2.2-r2
Tom Stellard před 14 roky
rodič
revize
8f32c6cfc6

+ 5
- 4
src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c Zobrazit soubor

@@ -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;

+ 1
- 1
src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c Zobrazit soubor

@@ -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;

+ 25
- 3
src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c Zobrazit soubor

@@ -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);
}
}


+ 3
- 1
src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h Zobrazit soubor

@@ -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);


+ 2
- 8
src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c Zobrazit soubor

@@ -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;

+ 6
- 5
src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c Zobrazit soubor

@@ -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;
}
}

+ 4
- 2
src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c Zobrazit soubor

@@ -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);
}

+ 2
- 20
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c Zobrazit soubor

@@ -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];

+ 1
- 1
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h Zobrazit soubor

@@ -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;
};

+ 1
- 1
src/mesa/drivers/dri/r300/compiler/radeon_program_print.c Zobrazit soubor

@@ -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");
}

Načítá se…
Zrušit
Uložit