Commit c70a116d by Nicolas Capens

Implement missing vector operations.

Bug swiftshader:15 Change-Id: I2116fa6ad368c801e921becd89259b02b4ca68ce Reviewed-on: https://swiftshader-review.googlesource.com/8251Reviewed-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent 45f187a3
......@@ -182,6 +182,49 @@ TEST(SubzeroReactorTest, VectorConstant)
delete routine;
}
TEST(SubzeroReactorTest, Concatenate)
{
Routine *routine = nullptr;
{
Function<Int(Pointer<Byte>)> function;
{
Pointer<Byte> out = function.Arg<0>();
*Pointer<Int4>(out + 16 * 0) = Int4(Int2(0x04030201, 0x08070605), Int2(0x0C0B0A09, 0x100F0E0D));
*Pointer<Short8>(out + 16 * 1) = Short8(Short4(0x0201, 0x0403, 0x0605, 0x0807), Short4(0x0A09, 0x0C0B, 0x0E0D, 0x100F));
Return(0);
}
routine = function(L"one");
if(routine)
{
int8_t ref[16 * 5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
int8_t out[16 * 5] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
int (*callable)(void*) = (int(*)(void*))routine->getEntry();
callable(out);
for(int row = 0; row < 2; row++)
{
for(int col = 0; col < 16; col++)
{
int i = row * 16 + col;
EXPECT_EQ(out[i], ref[i]) << "Row " << row << " column " << col << " not equal to reference.";
}
}
}
}
delete routine;
}
TEST(SubzeroReactorTest, Swizzle)
{
Routine *routine = nullptr;
......
......@@ -2904,7 +2904,7 @@ namespace sw
Short2::Short2(RValue<Short4> cast)
{
assert(false && "UNIMPLEMENTED");
storeValue(Nucleus::createBitCast(cast.value, getType()));
}
Type *Short2::getType()
......@@ -2914,7 +2914,7 @@ namespace sw
UShort2::UShort2(RValue<UShort4> cast)
{
assert(false && "UNIMPLEMENTED");
storeValue(Nucleus::createBitCast(cast.value, getType()));
}
Type *UShort2::getType()
......@@ -3637,7 +3637,10 @@ namespace sw
Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
{
assert(false && "UNIMPLEMENTED");
int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
storeValue(packed);
}
RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
......@@ -3700,7 +3703,10 @@ namespace sw
UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
{
assert(false && "UNIMPLEMENTED");
int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
storeValue(packed);
}
RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
......@@ -4230,7 +4236,18 @@ namespace sw
UInt::UInt(RValue<Float> cast)
{
assert(false && "UNIMPLEMENTED");
// Smallest positive value representable in UInt, but not in Int
const unsigned int ustart = 0x80000000u;
const float ustartf = float(ustart);
// If the value is negative, store 0, otherwise store the result of the conversion
storeValue((~(As<Int>(cast) >> 31) &
// Check if the value can be represented as an Int
IfThenElse(cast >= ustartf,
// If the value is too large, subtract ustart and re-add it after conversion.
As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
// Otherwise, just convert normally
Int(cast))).value);
}
UInt::UInt()
......@@ -4731,12 +4748,15 @@ namespace sw
RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
{
assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
}
RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
{
assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
int shuffle[16] = {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));
}
RValue<Int> Extract(RValue<Int2> val, int i)
......@@ -5077,7 +5097,10 @@ namespace sw
Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
{
assert(false && "UNIMPLEMENTED");
int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
storeValue(packed);
}
Int4::Int4(RValue<Int> rhs)
......@@ -5369,7 +5392,18 @@ namespace sw
{
// xyzw.parent = this;
assert(false && "UNIMPLEMENTED");
// Smallest positive value representable in UInt, but not in Int
const unsigned int ustart = 0x80000000u;
const float ustartf = float(ustart);
// Check if the value can be represented as an Int
Int4 uiValue = CmpNLT(cast, Float4(ustartf));
// If the value is too large, subtract ustart and re-add it after conversion.
uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
// Otherwise, just convert normally
(~uiValue & Int4(cast));
// If the value is negative, store 0, otherwise store the result of the conversion
storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
}
UInt4::UInt4()
......@@ -5453,7 +5487,10 @@ namespace sw
UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
{
assert(false && "UNIMPLEMENTED");
int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
storeValue(packed);
}
RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
......
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