Be more explicit with swizzling functions which ones override swizzles

This commit is contained in:
baldurk
2021-07-12 17:53:34 +01:00
parent 48fa6034ce
commit c18764d777
2 changed files with 99 additions and 44 deletions
+78 -23
View File
@@ -798,39 +798,94 @@ struct Operand
// .xyzw = { 0, 1, 2, 3 }
// .wzyx = { 3, 2, 1, 0 }
Operand swizzle(uint8_t c)
Operand &swizzle(uint8_t c)
{
Operand ret = *this;
ret.numComponents = NUMCOMPS_1;
ret.comps[0] = comps[c];
ret.comps[1] = 0xff;
ret.comps[2] = 0xff;
ret.comps[3] = 0xff;
ret.values[0] = values[c];
ret.values[1] = 0;
ret.values[2] = 0;
ret.values[3] = 0;
return ret;
// you'd think this would use NUMCOMPS_1 but fxc doesn't like that. Those only
// seem to be used for declarations or other special situations, so we keep to NUMCOMPS_4
flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED));
flags = Flags(flags | FLAG_SELECTED);
numComponents = NUMCOMPS_4;
comps[0] = c;
comps[1] = 0xff;
comps[2] = 0xff;
comps[3] = 0xff;
return *this;
}
Operand swizzle(uint8_t x, uint8_t y, uint8_t z, uint8_t w)
Operand &swizzle(uint8_t x, uint8_t y, uint8_t z, uint8_t w)
{
Operand ret = *this;
ret.comps[0] = comps[x];
ret.comps[1] = comps[y];
ret.comps[2] = z < 4 ? comps[z] : 0xff;
ret.comps[3] = w < 4 ? comps[w] : 0xff;
ret.values[0] = values[x];
ret.values[1] = values[y];
ret.values[2] = z < 4 ? values[z] : 0;
ret.values[3] = w < 4 ? values[w] : 0;
return ret;
numComponents = NUMCOMPS_4;
flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED));
if(x == 0xff || y == 0xff || z == 0xff || w == 0xff)
flags = Flags(flags | FLAG_MASKED);
else
flags = Flags(flags | FLAG_SWIZZLED);
comps[0] = x;
comps[1] = y;
comps[2] = z;
comps[3] = w;
return *this;
}
Operand &reswizzle(uint8_t c)
{
// you'd think this would use NUMCOMPS_1 but fxc doesn't like that. Those only
// seem to be used for declarations or other special situations, so we keep to NUMCOMPS_4
flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED));
flags = Flags(flags | FLAG_SELECTED);
numComponents = NUMCOMPS_4;
comps[0] = comps[c];
comps[1] = 0xff;
comps[2] = 0xff;
comps[3] = 0xff;
values[0] = values[c];
values[1] = 0;
values[2] = 0;
values[3] = 0;
return *this;
}
Operand &reswizzle(uint8_t x, uint8_t y, uint8_t z, uint8_t w)
{
rdcfixedarray<uint32_t, 4> oldVals = values;
rdcfixedarray<uint8_t, 4> oldComps = comps;
numComponents = NUMCOMPS_4;
flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED));
if(x == 0xff || y == 0xff || z == 0xff || w == 0xff)
flags = Flags(flags | FLAG_MASKED);
else
flags = Flags(flags | FLAG_SWIZZLED);
comps[0] = oldComps[x];
comps[1] = y < 4 ? oldComps[y] : 0xff;
comps[2] = z < 4 ? oldComps[z] : 0xff;
comps[3] = w < 4 ? oldComps[w] : 0xff;
values[0] = oldVals[x];
values[1] = z < 4 ? oldVals[y] : 0;
values[2] = z < 4 ? oldVals[z] : 0;
values[3] = w < 4 ? oldVals[w] : 0;
return *this;
}
void setComps(uint8_t x, uint8_t y, uint8_t z, uint8_t w)
{
flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED));
// you'd think this would use NUMCOMPS_1 but fxc doesn't like that. Those only
// seem to be used for declarations or other special situations, so we keep to NUMCOMPS_4
numComponents = NUMCOMPS_4;
if(y == 0xff && z == 0xff && w == 0xff)
flags = Flags(flags | FLAG_SELECTED);
else if(x == 0xff || y == 0xff || z == 0xff || w == 0xff)
@@ -717,10 +717,10 @@ void Program::PostprocessVendorExtensions()
}
else
{
op.operands.push_back(srcParam[5].swizzle(0));
op.operands.push_back(srcParam[5].reswizzle(0));
op.operands.back().name = "compare_value.x"_lit;
op.operands.back().setComps(srcParam[5].comps[0], 0xff, 0xff, 0xff);
op.operands.push_back(srcParam[6].swizzle(0));
op.operands.push_back(srcParam[6].reswizzle(0));
op.operands.back().name = "compare_value.y"_lit;
op.operands.back().setComps(srcParam[6].comps[0], 0xff, 0xff, 0xff);
@@ -742,10 +742,10 @@ void Program::PostprocessVendorExtensions()
}
else
{
op.operands.push_back(srcParam[3].swizzle(0));
op.operands.push_back(srcParam[3].reswizzle(0));
op.operands.back().name = "value.x"_lit;
op.operands.back().setComps(srcParam[3].comps[0], 0xff, 0xff, 0xff);
op.operands.push_back(srcParam[4].swizzle(0));
op.operands.push_back(srcParam[4].reswizzle(0));
op.operands.back().name = "value.y"_lit;
op.operands.back().setComps(srcParam[4].comps[0], 0xff, 0xff, 0xff);
@@ -919,16 +919,16 @@ void Program::PostprocessVendorExtensions()
op.operands[0] = curOp.operands[0];
op.operands[1].name = "value"_lit;
op.operands[1] = srcParam[0].swizzle(0);
op.operands[1] = srcParam[0].reswizzle(0);
if(nvopcode == NvShaderOpcode::Shuffle)
op.operands[2].name = "srcLane"_lit;
else if(nvopcode == NvShaderOpcode::ShuffleXor)
op.operands[2].name = "laneMask"_lit;
else
op.operands[2].name = "delta"_lit;
op.operands[2] = srcParam[0].swizzle(1);
op.operands[2] = srcParam[0].reswizzle(1);
op.operands[3].name = "width"_lit;
op.operands[3] = srcParam[0].swizzle(3);
op.operands[3] = srcParam[0].reswizzle(3);
break;
}
case NvShaderOpcode::VoteAll:
@@ -1077,33 +1077,33 @@ void Program::PostprocessVendorExtensions()
}
// peel out the source parameters
op.operands.push_back(srcParam[3].swizzle(0));
op.operands.push_back(srcParam[3].reswizzle(0));
op.operands.back().name = "texSpace"_lit;
op.operands.push_back(srcParam[0].swizzle(0));
op.operands.push_back(srcParam[0].reswizzle(0));
op.operands.back().name = "texIndex"_lit;
op.operands.push_back(srcParam[3].swizzle(1));
op.operands.push_back(srcParam[3].reswizzle(1));
op.operands.back().name = "smpSpace"_lit;
op.operands.push_back(srcParam[0].swizzle(1));
op.operands.push_back(srcParam[0].reswizzle(1));
op.operands.back().name = "smpIndex"_lit;
op.operands.push_back(srcParam[3].swizzle(2));
op.operands.push_back(srcParam[3].reswizzle(2));
op.operands.back().name = "texType"_lit;
op.operands.push_back(srcParam[1]);
op.operands.back().comps[3] = 0xff; // location is a float3
op.operands.back().values[3] = 0;
op.operands.back().name = "location"_lit;
op.operands.push_back(srcParam[3].swizzle(3));
op.operands.push_back(srcParam[3].reswizzle(3));
op.operands.back().name = "coarse"_lit;
op.operands.push_back(srcParam[1].swizzle(3));
op.operands.push_back(srcParam[1].reswizzle(3));
op.operands.back().name = "gran"_lit;
if(nvopcode == NvShaderOpcode::FootprintBias)
{
op.operands.push_back(srcParam[2].swizzle(0));
op.operands.push_back(srcParam[2].reswizzle(0));
op.operands.back().name = "bias"_lit;
}
else if(nvopcode == NvShaderOpcode::FootprintLevel)
{
op.operands.push_back(srcParam[2].swizzle(0));
op.operands.push_back(srcParam[2].reswizzle(0));
op.operands.back().name = "lodLevel"_lit;
}
else if(nvopcode == NvShaderOpcode::FootprintGrad)
@@ -1131,11 +1131,11 @@ void Program::PostprocessVendorExtensions()
// we expect the params are packed into srcParam[0]
op.operands[2] = srcParam[0].swizzle(0);
op.operands[2] = srcParam[0].reswizzle(0);
op.operands[2].name = "value"_lit;
op.operands[3] = srcParam[0].swizzle(1);
op.operands[3] = srcParam[0].reswizzle(1);
op.operands[3].name = "srcLane"_lit;
op.operands[4] = srcParam[0].swizzle(2);
op.operands[4] = srcParam[0].reswizzle(2);
op.operands[4].name = "width"_lit;
break;
}
@@ -1367,9 +1367,9 @@ void Program::PostprocessVendorExtensions()
atomicop = (NvShaderAtomic)srcParam[2].values[0];
op.operands.push_back(srcParam[0].swizzle(0));
op.operands.push_back(srcParam[0].reswizzle(0));
op.operands.back().name = "byteAddress"_lit;
op.operands.push_back(srcParam[1].swizzle(0));
op.operands.push_back(srcParam[1].reswizzle(0));
op.operands.back().name = "value"_lit;
break;