summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-08-20 18:44:47 -0500
committerGravatar Subv2018-08-20 18:44:47 -0500
commit2b9eee4d1ed13e98de21d88d8920288b58d7f4eb (patch)
tree81069cd0009f52ea42087bc332c3adf0a2951155 /src
parentGLState: Allow enabling/disabling GL_COLOR_LOGIC_OP independently from blending. (diff)
downloadyuzu-2b9eee4d1ed13e98de21d88d8920288b58d7f4eb.tar.gz
yuzu-2b9eee4d1ed13e98de21d88d8920288b58d7f4eb.tar.xz
yuzu-2b9eee4d1ed13e98de21d88d8920288b58d7f4eb.zip
GPU: Implemented the logic op functionality of the GPU.
This will ASSERT if blending is enabled at the same time as logic ops.
Diffstat (limited to 'src')
-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() {
449 449
450 SyncDepthTestState(); 450 SyncDepthTestState();
451 SyncBlendState(); 451 SyncBlendState();
452 SyncLogicOpState();
452 SyncCullMode(); 453 SyncCullMode();
453 454
454 // TODO(bunnei): Sync framebuffer_scale uniform here 455 // TODO(bunnei): Sync framebuffer_scale uniform here
@@ -847,6 +848,9 @@ void RasterizerOpenGL::SyncBlendState() {
847 if (!state.blend.enabled) 848 if (!state.blend.enabled)
848 return; 849 return;
849 850
851 ASSERT_MSG(regs.logic_op.enable == 0,
852 "Blending and logic op can't be enabled at the same time.");
853
850 ASSERT_MSG(regs.independent_blend_enable == 1, "Only independent blending is implemented"); 854 ASSERT_MSG(regs.independent_blend_enable == 1, "Only independent blending is implemented");
851 ASSERT_MSG(!regs.independent_blend[0].separate_alpha, "Unimplemented"); 855 ASSERT_MSG(!regs.independent_blend[0].separate_alpha, "Unimplemented");
852 state.blend.rgb_equation = MaxwellToGL::BlendEquation(regs.independent_blend[0].equation_rgb); 856 state.blend.rgb_equation = MaxwellToGL::BlendEquation(regs.independent_blend[0].equation_rgb);
@@ -856,3 +860,17 @@ void RasterizerOpenGL::SyncBlendState() {
856 state.blend.src_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_source_a); 860 state.blend.src_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_source_a);
857 state.blend.dst_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_dest_a); 861 state.blend.dst_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_dest_a);
858} 862}
863
864void RasterizerOpenGL::SyncLogicOpState() {
865 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
866
867 // TODO(Subv): Support more than just render target 0.
868 state.logic_op.enabled = regs.logic_op.enable != 0;
869
870 if (!state.logic_op.enabled)
871 return;
872
873 ASSERT_MSG(regs.blend.enable == 0, "Blending and logic op can't be enabled at the same time.");
874
875 state.logic_op.operation = MaxwellToGL::LogicOp(regs.logic_op.operation);
876}
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:
141 /// Syncs the blend state to match the guest state 141 /// Syncs the blend state to match the guest state
142 void SyncBlendState(); 142 void SyncBlendState();
143 143
144 /// Syncs the LogicOp state to match the guest state
145 void SyncLogicOpState();
146
144 bool has_ARB_direct_state_access = false; 147 bool has_ARB_direct_state_access = false;
145 bool has_ARB_separate_shader_objects = false; 148 bool has_ARB_separate_shader_objects = false;
146 bool has_ARB_vertex_attrib_binding = false; 149 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) {
317 return {}; 317 return {};
318} 318}
319 319
320inline GLenum LogicOp(Maxwell::LogicOperation operation) {
321 switch (operation) {
322 case Maxwell::LogicOperation::Clear:
323 return GL_CLEAR;
324 case Maxwell::LogicOperation::And:
325 return GL_AND;
326 case Maxwell::LogicOperation::AndReverse:
327 return GL_AND_REVERSE;
328 case Maxwell::LogicOperation::Copy:
329 return GL_COPY;
330 case Maxwell::LogicOperation::AndInverted:
331 return GL_AND_INVERTED;
332 case Maxwell::LogicOperation::NoOp:
333 return GL_NOOP;
334 case Maxwell::LogicOperation::Xor:
335 return GL_XOR;
336 case Maxwell::LogicOperation::Or:
337 return GL_OR;
338 case Maxwell::LogicOperation::Nor:
339 return GL_NOR;
340 case Maxwell::LogicOperation::Equiv:
341 return GL_EQUIV;
342 case Maxwell::LogicOperation::Invert:
343 return GL_INVERT;
344 case Maxwell::LogicOperation::OrReverse:
345 return GL_OR_REVERSE;
346 case Maxwell::LogicOperation::CopyInverted:
347 return GL_COPY_INVERTED;
348 case Maxwell::LogicOperation::OrInverted:
349 return GL_OR_INVERTED;
350 case Maxwell::LogicOperation::Nand:
351 return GL_NAND;
352 case Maxwell::LogicOperation::Set:
353 return GL_SET;
354 }
355 LOG_CRITICAL(Render_OpenGL, "Unimplemented logic operation={}", static_cast<u32>(operation));
356 UNREACHABLE();
357 return {};
358}
359
320} // namespace MaxwellToGL 360} // namespace MaxwellToGL