Commit 8701dc44 by Ben Clayton

Reactor: Switch swizzles over to 16-bit hex codes

This migrates from 2-bit swizzle codes per lane to 4-bit, which reads more fluently in hex. The order has been reversed so that the most significant nibble (leftmost on little-endian CPUs) represents the first output lane. Fixed up Swizzle, Mask, and ShuffleLowHigh Bug: b/145746360 Change-Id: I132bd757801a5ca543ef2b9b0ed34d0527db5bfa Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/39049 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarDavid Turner <digit@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com>
parent b9f03f47
......@@ -179,8 +179,8 @@ namespace sw
xLeft[q] = *Pointer<Short4>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline) + y * sizeof(Primitive::Span));
xRight[q] = xLeft[q];
xLeft[q] = Swizzle(xLeft[q], 0xA0) - Short4(1, 2, 1, 2);
xRight[q] = Swizzle(xRight[q], 0xF5) - Short4(0, 1, 0, 1);
xLeft[q] = Swizzle(xLeft[q], 0x0022) - Short4(1, 2, 1, 2);
xRight[q] = Swizzle(xRight[q], 0x1133) - Short4(0, 1, 0, 1);
}
For(Int x = x0, x < x1, x += 2)
......
......@@ -217,8 +217,8 @@ namespace sw
case FORMAT_A16B16G16R16:
For(, x < width - 1, x += 2)
{
Short4 c0 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 0), 0xC6)) >> 8;
Short4 c1 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 8), 0xC6)) >> 8;
Short4 c0 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 0), 0x2103)) >> 8;
Short4 c1 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 8), 0x2103)) >> 8;
*Pointer<Int2>(d) = As<Int2>(PackUnsigned(c0, c1));
......@@ -264,7 +264,7 @@ namespace sw
break;
case FORMAT_A16B16G16R16:
{
Short4 c = As<UShort4>(Swizzle(*Pointer<Short4>(s), 0xC6)) >> 8;
Short4 c = As<UShort4>(Swizzle(*Pointer<Short4>(s), 0x2103)) >> 8;
*Pointer<Int>(d) = Int(As<Int2>(PackUnsigned(c, c)));
}
......@@ -545,10 +545,10 @@ namespace sw
break;
case FORMAT_X8B8G8R8:
case FORMAT_A8B8G8R8:
c2 = Swizzle(Unpack(*Pointer<Byte4>(s)), 0xC6);
c2 = Swizzle(Unpack(*Pointer<Byte4>(s)), 0x2103);
break;
case FORMAT_A16B16G16R16:
c2 = Swizzle(*Pointer<Short4>(s), 0xC6);
c2 = Swizzle(*Pointer<Short4>(s), 0x2103);
break;
case FORMAT_R5G6B5:
{
......@@ -568,7 +568,7 @@ namespace sw
c1 = As<Short4>(As<UShort4>(c1) >> 9);
c2 = As<Short4>(As<UShort4>(c2) >> 9);
Short4 alpha = Swizzle(c1, 0xFF) & Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0x0000);
Short4 alpha = Swizzle(c1, 0x3333) & Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0x0000);
c1 = (c1 - c2) * alpha;
c1 = c1 >> 7;
......@@ -586,7 +586,7 @@ namespace sw
case FORMAT_SRGB8_X8:
case FORMAT_SRGB8_A8:
{
c1 = Swizzle(c1, 0xC6);
c1 = Swizzle(c1, 0x2103);
*Pointer<Byte4>(d) = Byte4(PackUnsigned(c1, c1));
}
......
......@@ -1852,8 +1852,8 @@ namespace sw
buffer += *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index]));
pixel.y = *Pointer<Float4>(buffer + 8 * x, 16);
pixel.z = pixel.x;
pixel.x = ShuffleLowHigh(pixel.x, pixel.y, 0x88);
pixel.z = ShuffleLowHigh(pixel.z, pixel.y, 0xDD);
pixel.x = ShuffleLowHigh(pixel.x, pixel.y, 0x0202);
pixel.z = ShuffleLowHigh(pixel.z, pixel.y, 0x1313);
pixel.y = pixel.z;
pixel.z = pixel.w = one;
break;
......
......@@ -2604,7 +2604,7 @@ namespace rr
#else
auto result = V(lowerPack(V(x.value), V(y.value), true));
#endif
return As<SByte8>(Swizzle(As<Int4>(result), 0x88));
return As<SByte8>(Swizzle(As<Int4>(result), 0x0202));
}
RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y)
......@@ -2615,7 +2615,7 @@ namespace rr
#else
auto result = V(lowerPack(V(x.value), V(y.value), false));
#endif
return As<Byte8>(Swizzle(As<Int4>(result), 0x88));
return As<Byte8>(Swizzle(As<Int4>(result), 0x0202));
}
RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
......
......@@ -113,18 +113,17 @@ namespace rr
//
// msb lsb
// v v
// [.aaa|.bbb|.ccc|.ddd] where '.' means an ignored bit
// [.xxx|.yyy|.zzz|.www] where '.' means an ignored bit
//
// This format makes it easy to write calls with hexadecimal select values,
// since each hex digit is a separate swizzle index. Note that the order
// of indices is reversed compared to createSwizzle4() below!
// since each hex digit is a separate swizzle index.
//
// For example:
// createBlend4( [a,b,c,d], [e,f,g,h], 0x0123 ) -> [a,b,c,d]
// createBlend4( [a,b,c,d], [e,f,g,h], 0x4567 ) -> [e,f,g,h]
// createBlend4( [a,b,c,d], [e,f,g,h], 0x4012 ) -> [e,a,b,c]
//
static Value *createBlend4(Value *lhs, Value *rhs, unsigned short select)
static Value *createBlend4(Value *lhs, Value *rhs, uint16_t select)
{
int swizzle[4] =
{
......@@ -137,27 +136,41 @@ namespace rr
return Nucleus::createShuffleVector(lhs, rhs, swizzle);
}
static Value *createSwizzle4(Value *val, unsigned char select)
// NOTE: Only 8 bits out of 16 of the |select| value are used.
// More specifically, the value should look like:
//
// msb lsb
// v v
// [..xx|..yy|..zz|..ww] where '.' means an ignored bit
//
// This format makes it easy to write calls with hexadecimal select values,
// since each hex digit is a separate swizzle index.
//
// For example:
// createSwizzle4( [a,b,c,d], 0x0123 ) -> [a,b,c,d]
// createSwizzle4( [a,b,c,d], 0x0033 ) -> [a,a,d,d]
//
static Value *createSwizzle4(Value *val, uint16_t select)
{
int swizzle[4] =
{
(select >> 0) & 0x03,
(select >> 2) & 0x03,
(select >> 4) & 0x03,
(select >> 6) & 0x03,
(select >> 12) & 0x03,
(select >> 8) & 0x03,
(select >> 4) & 0x03,
(select >> 0) & 0x03,
};
return Nucleus::createShuffleVector(val, val, swizzle);
}
static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
static Value *createMask4(Value *lhs, Value *rhs, uint16_t select)
{
bool mask[4] = {false, false, false, false};
mask[(select >> 0) & 0x03] = true;
mask[(select >> 2) & 0x03] = true;
mask[(select >> 4) & 0x03] = true;
mask[(select >> 6) & 0x03] = true;
mask[(select >> 12) & 0x03] = true;
mask[(select >> 8) & 0x03] = true;
mask[(select >> 4) & 0x03] = true;
mask[(select >> 0) & 0x03] = true;
int swizzle[4] =
{
......@@ -1428,7 +1441,7 @@ namespace rr
{
int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
return As<Short4>(Swizzle(As<Int4>(lowHigh), 0x2323));
}
SByte8::SByte8(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
......@@ -1604,7 +1617,7 @@ namespace rr
{
int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
return As<Short4>(Swizzle(As<Int4>(lowHigh), 0x2323));
}
Byte16::Byte16(RValue<Byte16> rhs)
......@@ -1662,7 +1675,7 @@ namespace rr
Value *vector = loadValue();
Value *element = Nucleus::createTrunc(cast.value, Short::getType());
Value *insert = Nucleus::createInsertElement(vector, element, 0);
Value *swizzle = Swizzle(RValue<Short4>(insert), 0x00).value;
Value *swizzle = Swizzle(RValue<Short4>(insert), 0x0000).value;
storeValue(swizzle);
}
......@@ -1882,22 +1895,22 @@ namespace rr
{
int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
return As<Int2>(Swizzle(As<Int4>(lowHigh), 0x2323));
}
RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
RValue<Short4> Swizzle(RValue<Short4> x, uint16_t select)
{
// Real type is v8i16
int shuffle[8] =
{
(select >> 0) & 0x03,
(select >> 2) & 0x03,
(select >> 4) & 0x03,
(select >> 6) & 0x03,
(select >> 0) & 0x03,
(select >> 2) & 0x03,
(select >> 4) & 0x03,
(select >> 6) & 0x03,
(select >> 12) & 0x03,
(select >> 8) & 0x03,
(select >> 4) & 0x03,
(select >> 0) & 0x03,
(select >> 12) & 0x03,
(select >> 8) & 0x03,
(select >> 4) & 0x03,
(select >> 0) & 0x03,
};
return As<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
......@@ -3094,7 +3107,7 @@ namespace rr
{
int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
return As<Short4>(Swizzle(lowHigh, 0xEE));
return As<Short4>(Swizzle(lowHigh, 0x2323));
}
RValue<Int> Extract(RValue<Int2> val, int i)
......@@ -3505,7 +3518,7 @@ namespace rr
return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
}
RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
RValue<Int4> Swizzle(RValue<Int4> x, uint16_t select)
{
return RValue<Int4>(createSwizzle4(x.value, select));
}
......@@ -3745,7 +3758,7 @@ namespace rr
return RValue<UInt4>(Nucleus::createInsertElement(x.value, element.value, i));
}
RValue<UInt4> Swizzle(RValue<UInt4> x, unsigned char select)
RValue<UInt4> Swizzle(RValue<UInt4> x, uint16_t select)
{
return RValue<UInt4>(createSwizzle4(x.value, select));
}
......@@ -4245,24 +4258,24 @@ namespace rr
return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
}
RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
RValue<Float4> Swizzle(RValue<Float4> x, uint16_t select)
{
return RValue<Float4>(createSwizzle4(x.value, select));
}
RValue<Float4> Blend(RValue<Float4> x, RValue<Float4> y, unsigned short select)
RValue<Float4> Blend(RValue<Float4> x, RValue<Float4> y, uint16_t select)
{
return RValue<Float4>(createBlend4(x.value, y.value, select));
}
RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, uint16_t imm)
{
int shuffle[4] =
{
((imm >> 0) & 0x03) + 0,
((imm >> 2) & 0x03) + 0,
((imm >> 4) & 0x03) + 4,
((imm >> 6) & 0x03) + 4,
((imm >> 12) & 0x03) + 0,
((imm >> 8) & 0x03) + 0,
((imm >> 4) & 0x03) + 4,
((imm >> 0) & 0x03) + 4,
};
return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
......@@ -4280,7 +4293,7 @@ namespace rr
return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
}
RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, uint16_t select)
{
Value *vector = lhs.loadValue();
Value *result = createMask4(vector, rhs.value, select);
......
......@@ -349,6 +349,15 @@ TEST(ReactorUnitTests, Concatenate)
TEST(ReactorUnitTests, Swizzle)
{
auto swizzleCode = [](int i) -> uint16_t
{
auto x = (i >> 0) & 0x03;
auto y = (i >> 2) & 0x03;
auto z = (i >> 4) & 0x03;
auto w = (i >> 6) & 0x03;
return (x << 12) | (y << 8) | (z << 4) | (w << 0);
};
{
FunctionT<int(void*)> function;
{
......@@ -356,12 +365,12 @@ TEST(ReactorUnitTests, Swizzle)
for(int i = 0; i < 256; i++)
{
*Pointer<Float4>(out + 16 * i) = Swizzle(Float4(1.0f, 2.0f, 3.0f, 4.0f), i);
*Pointer<Float4>(out + 16 * i) = Swizzle(Float4(1.0f, 2.0f, 3.0f, 4.0f), swizzleCode(i));
}
for(int i = 0; i < 256; i++)
{
*Pointer<Float4>(out + 16 * (256 + i)) = ShuffleLowHigh(Float4(1.0f, 2.0f, 3.0f, 4.0f), Float4(5.0f, 6.0f, 7.0f, 8.0f), i);
{
*Pointer<Float4>(out + 16 * (256 + i)) = ShuffleLowHigh(Float4(1.0f, 2.0f, 3.0f, 4.0f), Float4(5.0f, 6.0f, 7.0f, 8.0f), swizzleCode(i));
}
*Pointer<Float4>(out + 16 * (512 + 0)) = UnpackLow(Float4(1.0f, 2.0f, 3.0f, 4.0f), Float4(5.0f, 6.0f, 7.0f, 8.0f));
......@@ -374,13 +383,13 @@ TEST(ReactorUnitTests, Swizzle)
for(int i = 0; i < 256; i++)
{
*Pointer<Short4>(out + 16 * (512 + 6) + (8 * i)) =
Swizzle(Short4(1, 2, 3, 4), i);
Swizzle(Short4(1, 2, 3, 4), swizzleCode(i));
}
for(int i = 0; i < 256; i++)
{
*Pointer<Int4>(out + 16 * (512 + 6 + i) + (8 * 256)) =
Swizzle(Int4(1, 2, 3, 4), i);
Swizzle(Int4(1, 2, 3, 4), swizzleCode(i));
}
Return(0);
......
......@@ -2202,7 +2202,7 @@ namespace rr
pack->addArg(y.value);
::basicBlock->appendInst(pack);
return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x0202));
}
}
......@@ -2232,7 +2232,7 @@ namespace rr
pack->addArg(y.value);
::basicBlock->appendInst(pack);
return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x0202));
}
}
......
......@@ -272,8 +272,8 @@ namespace sw
xLeft[q] = *Pointer<Short4>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline) + y * sizeof(Primitive::Span));
xRight[q] = xLeft[q];
xLeft[q] = Swizzle(xLeft[q], 0xA0) - Short4(1, 2, 1, 2);
xRight[q] = Swizzle(xRight[q], 0xF5) - Short4(0, 1, 0, 1);
xLeft[q] = Swizzle(xLeft[q], 0x0022) - Short4(1, 2, 1, 2);
xRight[q] = Swizzle(xRight[q], 0x1133) - Short4(0, 1, 0, 1);
}
For(Int x = x0, x < x1, x += 2)
......
......@@ -2081,8 +2081,8 @@ namespace sw
buffer += *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index]));
pixel.y = *Pointer<Float4>(buffer + 8 * x, 16);
pixel.z = pixel.x;
pixel.x = ShuffleLowHigh(pixel.x, pixel.y, 0x88);
pixel.z = ShuffleLowHigh(pixel.z, pixel.y, 0xDD);
pixel.x = ShuffleLowHigh(pixel.x, pixel.y, 0x0202);
pixel.z = ShuffleLowHigh(pixel.z, pixel.y, 0x1313);
pixel.y = pixel.z;
pixel.z = pixel.w = one;
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment