GPU: Implemented the logic op functionality of the GPU.
This will ASSERT if blending is enabled at the same time as logic ops.
This commit is contained in:
parent
f24ab6d9e6
commit
2b9eee4d1e
|
@ -449,6 +449,7 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
|
|
||||||
SyncDepthTestState();
|
SyncDepthTestState();
|
||||||
SyncBlendState();
|
SyncBlendState();
|
||||||
|
SyncLogicOpState();
|
||||||
SyncCullMode();
|
SyncCullMode();
|
||||||
|
|
||||||
// TODO(bunnei): Sync framebuffer_scale uniform here
|
// TODO(bunnei): Sync framebuffer_scale uniform here
|
||||||
|
@ -847,6 +848,9 @@ void RasterizerOpenGL::SyncBlendState() {
|
||||||
if (!state.blend.enabled)
|
if (!state.blend.enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ASSERT_MSG(regs.logic_op.enable == 0,
|
||||||
|
"Blending and logic op can't be enabled at the same time.");
|
||||||
|
|
||||||
ASSERT_MSG(regs.independent_blend_enable == 1, "Only independent blending is implemented");
|
ASSERT_MSG(regs.independent_blend_enable == 1, "Only independent blending is implemented");
|
||||||
ASSERT_MSG(!regs.independent_blend[0].separate_alpha, "Unimplemented");
|
ASSERT_MSG(!regs.independent_blend[0].separate_alpha, "Unimplemented");
|
||||||
state.blend.rgb_equation = MaxwellToGL::BlendEquation(regs.independent_blend[0].equation_rgb);
|
state.blend.rgb_equation = MaxwellToGL::BlendEquation(regs.independent_blend[0].equation_rgb);
|
||||||
|
@ -856,3 +860,17 @@ void RasterizerOpenGL::SyncBlendState() {
|
||||||
state.blend.src_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_source_a);
|
state.blend.src_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_source_a);
|
||||||
state.blend.dst_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_dest_a);
|
state.blend.dst_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_dest_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerOpenGL::SyncLogicOpState() {
|
||||||
|
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
|
||||||
|
|
||||||
|
// TODO(Subv): Support more than just render target 0.
|
||||||
|
state.logic_op.enabled = regs.logic_op.enable != 0;
|
||||||
|
|
||||||
|
if (!state.logic_op.enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ASSERT_MSG(regs.blend.enable == 0, "Blending and logic op can't be enabled at the same time.");
|
||||||
|
|
||||||
|
state.logic_op.operation = MaxwellToGL::LogicOp(regs.logic_op.operation);
|
||||||
|
}
|
||||||
|
|
|
@ -141,6 +141,9 @@ private:
|
||||||
/// Syncs the blend state to match the guest state
|
/// Syncs the blend state to match the guest state
|
||||||
void SyncBlendState();
|
void SyncBlendState();
|
||||||
|
|
||||||
|
/// Syncs the LogicOp state to match the guest state
|
||||||
|
void SyncLogicOpState();
|
||||||
|
|
||||||
bool has_ARB_direct_state_access = false;
|
bool has_ARB_direct_state_access = false;
|
||||||
bool has_ARB_separate_shader_objects = false;
|
bool has_ARB_separate_shader_objects = false;
|
||||||
bool has_ARB_vertex_attrib_binding = false;
|
bool has_ARB_vertex_attrib_binding = false;
|
||||||
|
|
|
@ -317,4 +317,44 @@ inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline GLenum LogicOp(Maxwell::LogicOperation operation) {
|
||||||
|
switch (operation) {
|
||||||
|
case Maxwell::LogicOperation::Clear:
|
||||||
|
return GL_CLEAR;
|
||||||
|
case Maxwell::LogicOperation::And:
|
||||||
|
return GL_AND;
|
||||||
|
case Maxwell::LogicOperation::AndReverse:
|
||||||
|
return GL_AND_REVERSE;
|
||||||
|
case Maxwell::LogicOperation::Copy:
|
||||||
|
return GL_COPY;
|
||||||
|
case Maxwell::LogicOperation::AndInverted:
|
||||||
|
return GL_AND_INVERTED;
|
||||||
|
case Maxwell::LogicOperation::NoOp:
|
||||||
|
return GL_NOOP;
|
||||||
|
case Maxwell::LogicOperation::Xor:
|
||||||
|
return GL_XOR;
|
||||||
|
case Maxwell::LogicOperation::Or:
|
||||||
|
return GL_OR;
|
||||||
|
case Maxwell::LogicOperation::Nor:
|
||||||
|
return GL_NOR;
|
||||||
|
case Maxwell::LogicOperation::Equiv:
|
||||||
|
return GL_EQUIV;
|
||||||
|
case Maxwell::LogicOperation::Invert:
|
||||||
|
return GL_INVERT;
|
||||||
|
case Maxwell::LogicOperation::OrReverse:
|
||||||
|
return GL_OR_REVERSE;
|
||||||
|
case Maxwell::LogicOperation::CopyInverted:
|
||||||
|
return GL_COPY_INVERTED;
|
||||||
|
case Maxwell::LogicOperation::OrInverted:
|
||||||
|
return GL_OR_INVERTED;
|
||||||
|
case Maxwell::LogicOperation::Nand:
|
||||||
|
return GL_NAND;
|
||||||
|
case Maxwell::LogicOperation::Set:
|
||||||
|
return GL_SET;
|
||||||
|
}
|
||||||
|
LOG_CRITICAL(Render_OpenGL, "Unimplemented logic operation={}", static_cast<u32>(operation));
|
||||||
|
UNREACHABLE();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace MaxwellToGL
|
} // namespace MaxwellToGL
|
||||||
|
|
Reference in New Issue