mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 02:31:04 +00:00
Add logic ops according to OpenGL ES 1.1 spec and 3dbrew.
This commit is contained in:
parent
40d1f9045a
commit
fba3ceb78f
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user