Commit 98436737 by Nicolas Capens Committed by Nicolas Capens

Emulate saturated vector add/subtract.

Bug b/37495545 Change-Id: I767f7b5555706cd42b80863fe1ae04b36f4f1189 Reviewed-on: https://swiftshader-review.googlesource.com/10932Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent d6cacadd
...@@ -2720,8 +2720,29 @@ namespace sw ...@@ -2720,8 +2720,29 @@ namespace sw
return RValue<Byte8>(Nucleus::createInsertElement(val.value, element.value, i)); return RValue<Byte8>(Nucleus::createInsertElement(val.value, element.value, i));
} }
RValue<Byte> Saturate(RValue<UShort> x)
{
return Byte(IfThenElse(Int(x) > 0xFF, Int(0xFF), Int(x)));
}
RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y) RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
{ {
if(emulateIntrinsics)
{
Byte8 result;
result = Insert(result, Saturate(UShort(Int(Extract(x, 0))) + UShort(Int(Extract(y, 0)))), 0);
result = Insert(result, Saturate(UShort(Int(Extract(x, 1))) + UShort(Int(Extract(y, 1)))), 1);
result = Insert(result, Saturate(UShort(Int(Extract(x, 2))) + UShort(Int(Extract(y, 2)))), 2);
result = Insert(result, Saturate(UShort(Int(Extract(x, 3))) + UShort(Int(Extract(y, 3)))), 3);
result = Insert(result, Saturate(UShort(Int(Extract(x, 4))) + UShort(Int(Extract(y, 4)))), 4);
result = Insert(result, Saturate(UShort(Int(Extract(x, 5))) + UShort(Int(Extract(y, 5)))), 5);
result = Insert(result, Saturate(UShort(Int(Extract(x, 6))) + UShort(Int(Extract(y, 6)))), 6);
result = Insert(result, Saturate(UShort(Int(Extract(x, 7))) + UShort(Int(Extract(y, 7)))), 7);
return result;
}
else
{
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8); Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
auto target = ::context->getConstantUndef(Ice::IceType_i32); auto target = ::context->getConstantUndef(Ice::IceType_i32);
...@@ -2732,9 +2753,26 @@ namespace sw ...@@ -2732,9 +2753,26 @@ namespace sw
return RValue<Byte8>(V(result)); return RValue<Byte8>(V(result));
} }
}
RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y) RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
{ {
if(emulateIntrinsics)
{
Byte8 result;
result = Insert(result, Saturate(UShort(Int(Extract(x, 0))) - UShort(Int(Extract(y, 0)))), 0);
result = Insert(result, Saturate(UShort(Int(Extract(x, 1))) - UShort(Int(Extract(y, 1)))), 1);
result = Insert(result, Saturate(UShort(Int(Extract(x, 2))) - UShort(Int(Extract(y, 2)))), 2);
result = Insert(result, Saturate(UShort(Int(Extract(x, 3))) - UShort(Int(Extract(y, 3)))), 3);
result = Insert(result, Saturate(UShort(Int(Extract(x, 4))) - UShort(Int(Extract(y, 4)))), 4);
result = Insert(result, Saturate(UShort(Int(Extract(x, 5))) - UShort(Int(Extract(y, 5)))), 5);
result = Insert(result, Saturate(UShort(Int(Extract(x, 6))) - UShort(Int(Extract(y, 6)))), 6);
result = Insert(result, Saturate(UShort(Int(Extract(x, 7))) - UShort(Int(Extract(y, 7)))), 7);
return result;
}
else
{
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8); Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
auto target = ::context->getConstantUndef(Ice::IceType_i32); auto target = ::context->getConstantUndef(Ice::IceType_i32);
...@@ -2745,6 +2783,7 @@ namespace sw ...@@ -2745,6 +2783,7 @@ namespace sw
return RValue<Byte8>(V(result)); return RValue<Byte8>(V(result));
} }
}
RValue<Short4> Unpack(RValue<Byte4> x) RValue<Short4> Unpack(RValue<Byte4> x)
{ {
...@@ -3008,8 +3047,29 @@ namespace sw ...@@ -3008,8 +3047,29 @@ namespace sw
return RValue<SByte8>(Nucleus::createNot(val.value)); return RValue<SByte8>(Nucleus::createNot(val.value));
} }
RValue<SByte> Saturate(RValue<Short> x)
{
return SByte(IfThenElse(Int(x) > 0x7F, Int(0x7F), IfThenElse(Int(x) < -0x80, Int(0x80), Int(x))));
}
RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y) RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
{ {
if(emulateIntrinsics)
{
SByte8 result;
result = Insert(result, Saturate(Short(Int(Extract(x, 0))) + Short(Int(Extract(y, 0)))), 0);
result = Insert(result, Saturate(Short(Int(Extract(x, 1))) + Short(Int(Extract(y, 1)))), 1);
result = Insert(result, Saturate(Short(Int(Extract(x, 2))) + Short(Int(Extract(y, 2)))), 2);
result = Insert(result, Saturate(Short(Int(Extract(x, 3))) + Short(Int(Extract(y, 3)))), 3);
result = Insert(result, Saturate(Short(Int(Extract(x, 4))) + Short(Int(Extract(y, 4)))), 4);
result = Insert(result, Saturate(Short(Int(Extract(x, 5))) + Short(Int(Extract(y, 5)))), 5);
result = Insert(result, Saturate(Short(Int(Extract(x, 6))) + Short(Int(Extract(y, 6)))), 6);
result = Insert(result, Saturate(Short(Int(Extract(x, 7))) + Short(Int(Extract(y, 7)))), 7);
return result;
}
else
{
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8); Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
auto target = ::context->getConstantUndef(Ice::IceType_i32); auto target = ::context->getConstantUndef(Ice::IceType_i32);
...@@ -3020,9 +3080,26 @@ namespace sw ...@@ -3020,9 +3080,26 @@ namespace sw
return RValue<SByte8>(V(result)); return RValue<SByte8>(V(result));
} }
}
RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y) RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
{ {
if(emulateIntrinsics)
{
SByte8 result;
result = Insert(result, Saturate(Short(Int(Extract(x, 0))) - Short(Int(Extract(y, 0)))), 0);
result = Insert(result, Saturate(Short(Int(Extract(x, 1))) - Short(Int(Extract(y, 1)))), 1);
result = Insert(result, Saturate(Short(Int(Extract(x, 2))) - Short(Int(Extract(y, 2)))), 2);
result = Insert(result, Saturate(Short(Int(Extract(x, 3))) - Short(Int(Extract(y, 3)))), 3);
result = Insert(result, Saturate(Short(Int(Extract(x, 4))) - Short(Int(Extract(y, 4)))), 4);
result = Insert(result, Saturate(Short(Int(Extract(x, 5))) - Short(Int(Extract(y, 5)))), 5);
result = Insert(result, Saturate(Short(Int(Extract(x, 6))) - Short(Int(Extract(y, 6)))), 6);
result = Insert(result, Saturate(Short(Int(Extract(x, 7))) - Short(Int(Extract(y, 7)))), 7);
return result;
}
else
{
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8); Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
auto target = ::context->getConstantUndef(Ice::IceType_i32); auto target = ::context->getConstantUndef(Ice::IceType_i32);
...@@ -3033,6 +3110,7 @@ namespace sw ...@@ -3033,6 +3110,7 @@ namespace sw
return RValue<SByte8>(V(result)); return RValue<SByte8>(V(result));
} }
}
RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y) RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
{ {
...@@ -3446,8 +3524,25 @@ namespace sw ...@@ -3446,8 +3524,25 @@ namespace sw
return RValue<Short4>(V(result)); return RValue<Short4>(V(result));
} }
RValue<Short> Saturate(RValue<Int> x)
{
return Short(IfThenElse(x > 0x7FFF, Int(0x7FFF), IfThenElse(x < -0x8000, Int(0x8000), x)));
}
RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y) RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
{ {
if(emulateIntrinsics)
{
Short4 result;
result = Insert(result, Saturate(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
result = Insert(result, Saturate(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
result = Insert(result, Saturate(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
result = Insert(result, Saturate(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
return result;
}
else
{
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16); Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
auto target = ::context->getConstantUndef(Ice::IceType_i32); auto target = ::context->getConstantUndef(Ice::IceType_i32);
...@@ -3458,9 +3553,22 @@ namespace sw ...@@ -3458,9 +3553,22 @@ namespace sw
return RValue<Short4>(V(result)); return RValue<Short4>(V(result));
} }
}
RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y) RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
{ {
if(emulateIntrinsics)
{
Short4 result;
result = Insert(result, Saturate(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
result = Insert(result, Saturate(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
result = Insert(result, Saturate(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
result = Insert(result, Saturate(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
return result;
}
else
{
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16); Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
auto target = ::context->getConstantUndef(Ice::IceType_i32); auto target = ::context->getConstantUndef(Ice::IceType_i32);
...@@ -3471,6 +3579,7 @@ namespace sw ...@@ -3471,6 +3579,7 @@ namespace sw
return RValue<Short4>(V(result)); return RValue<Short4>(V(result));
} }
}
RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y) RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
{ {
...@@ -3801,8 +3910,25 @@ namespace sw ...@@ -3801,8 +3910,25 @@ namespace sw
return RValue<UShort4>(V(result)); return RValue<UShort4>(V(result));
} }
RValue<UShort> SaturateUShort(RValue<Int> x)
{
return UShort(IfThenElse(x > 0xFFFF, Int(0xFFFF), IfThenElse(x < 0, Int(0), x)));
}
RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y) RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
{ {
if(emulateIntrinsics)
{
UShort4 result;
result = Insert(result, SaturateUShort(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
result = Insert(result, SaturateUShort(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
result = Insert(result, SaturateUShort(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
result = Insert(result, SaturateUShort(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
return result;
}
else
{
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16); Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
auto target = ::context->getConstantUndef(Ice::IceType_i32); auto target = ::context->getConstantUndef(Ice::IceType_i32);
...@@ -3813,9 +3939,22 @@ namespace sw ...@@ -3813,9 +3939,22 @@ namespace sw
return RValue<UShort4>(V(result)); return RValue<UShort4>(V(result));
} }
}
RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y) RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
{ {
if(emulateIntrinsics)
{
UShort4 result;
result = Insert(result, SaturateUShort(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
result = Insert(result, SaturateUShort(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
result = Insert(result, SaturateUShort(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
result = Insert(result, SaturateUShort(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
return result;
}
else
{
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16); Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
auto target = ::context->getConstantUndef(Ice::IceType_i32); auto target = ::context->getConstantUndef(Ice::IceType_i32);
...@@ -3826,6 +3965,7 @@ namespace sw ...@@ -3826,6 +3965,7 @@ namespace sw
return RValue<UShort4>(V(result)); return RValue<UShort4>(V(result));
} }
}
RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y) RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
{ {
......
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