summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h40
3 files changed, 61 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index fe1f55e85..a8669efdf 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -449,6 +449,7 @@ void RasterizerOpenGL::DrawArrays() {
SyncDepthTestState();
SyncBlendState();
+ SyncLogicOpState();
SyncCullMode();
// TODO(bunnei): Sync framebuffer_scale uniform here
@@ -847,6 +848,9 @@ void RasterizerOpenGL::SyncBlendState() {
if (!state.blend.enabled)
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[0].separate_alpha, "Unimplemented");
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.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);
+}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 74307f626..0cca7d760 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -141,6 +141,9 @@ private:
/// Syncs the blend state to match the guest state
void SyncBlendState();
+ /// Syncs the LogicOp state to match the guest state
+ void SyncLogicOpState();
+
bool has_ARB_direct_state_access = false;
bool has_ARB_separate_shader_objects = false;
bool has_ARB_vertex_attrib_binding = false;
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 5d91a0c2f..ff2f7b8b6 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -317,4 +317,44 @@ inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) {
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