Add logic ops according to OpenGL ES 1.1 spec and 3dbrew.

This commit is contained in:
Darius Goad 2015-02-25 12:25:06 -06:00
parent 40d1f9045a
commit fba3ceb78f
3 changed files with 117 additions and 2 deletions

View File

@ -424,6 +424,27 @@ public:
return x*x + y*y + z*z + w*w;
}
// Needed for logic ops
Vec4<decltype(~T{})> operator ~() const
{
return MakeVec(~x,~y,~z,~w);
}
Vec4<decltype(T{}&T{})> operator &(const Vec4& other) const
{
return MakeVec(x&other.x, y&other.y, z&other.z, w&other.w);
}
Vec4<decltype(T{}|T{})> operator |(const Vec4& other) const
{
return MakeVec(x|other.x, y|other.y, z|other.z, w|other.w);
}
Vec4<decltype(T{}^T{})> operator ^(const Vec4& other) const
{
return MakeVec(x^other.x, y^other.y, z^other.z, w^other.w);
}
// Only implemented for T=float
float Length() const;
void SetLength(const float l);

View File

@ -374,7 +374,22 @@ struct Regs {
union {
enum Op {
Clear = 0,
And = 1,
AndReverse = 2,
Copy = 3,
Set = 4,
CopyInverted = 5,
NoOp = 6,
Invert = 7,
Nand = 8,
Or = 9,
Nor = 10,
Xor = 11,
Equiv = 12,
AndInverted = 13,
OrReverse = 14,
OrInverted = 15,
};
BitField<0, 4, Op> op;

View File

@ -778,8 +778,87 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
blend_output = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor, params.blend_equation_rgb);
blend_output.a() = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor, params.blend_equation_a).a();
} else {
LOG_CRITICAL(HW_GPU, "logic op: %x", registers.output_merger.logic_op);
UNIMPLEMENTED();
auto params = registers.output_merger.logic_op;
using LogicOp = decltype(params)::Op;
auto EvaluateLogicOp = [&](const Math::Vec4<u8>& src, const Math::Vec4<u8>& dest
LogicOp op) -> Math::Vec4<u8> {
Math::Vec4<u8> result;
switch(op) {
case LogicOp::Clear:
result = Math::Vec4<u8>(0,0,0,0);
break;
case LogicOp::And:
result = src & dest;
break;
case LogicOp::AndReverse:
result = src & ~dest;
break;
case LogicOp::Copy:
result = src;
break;
case LogicOp::Set:
result = Math::Vec4<u8>(1,1,1,1);
break;
case LogicOp::CopyInverted:
result = ~src;
break;
case LogicOp::NoOp:
result = dest;
break;
case LogicOp::Invert:
result = ~dest;
break;
case LogicOp::Nand:
result = ~(src & dest);
break;
case LogicOp::Or:
result = src | dest;
break;
case LogicOp::Nor:
result = ~(src | dest);
break;
case LogicOp::Xor:
result = src ^ dest;
break;
case LogicOp::Equiv:
result = ~(src ^ dest);
break;
case LogicOp::AndInverted:
result = ~src & dest;
break;
case LogicOp::OrReverse:
result = src | ~dest;
break;
case LogicOp::OrInverted:
result = ~src | dest;
break;
default:
LOG_CRITICAL(HW_GPU, "Unknown logic op %x", op);
UNIMPLEMENTED();
}
return result;
};
blend_output = EvaluateLogicOp(combiner_output, dest, params.op);
}
const Math::Vec4<u8> result = {