From 174cba5c586e14445d28a1fc36148178540ff57b Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 13 Apr 2018 23:13:47 -0400 Subject: renderer_opengl: Implement BlendEquation and BlendFunc. --- src/video_core/engines/maxwell_3d.cpp | 4 +- src/video_core/engines/maxwell_3d.h | 48 +++++++++++++++++- src/video_core/rasterizer_interface.h | 2 +- src/video_core/renderer_opengl/gl_rasterizer.cpp | 27 +++++++++- src/video_core/renderer_opengl/gl_rasterizer.h | 2 +- src/video_core/renderer_opengl/maxwell_to_gl.h | 64 ++++++++++++++++++++++++ 6 files changed, 140 insertions(+), 7 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 0e1d6d785..41f0e5c9b 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -74,8 +74,6 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { regs.reg_array[method] = value; -#define MAXWELL3D_REG_INDEX(field_name) (offsetof(Regs, field_name) / sizeof(u32)) - switch (method) { case MAXWELL3D_REG_INDEX(code_address.code_address_high): case MAXWELL3D_REG_INDEX(code_address.code_address_low): { @@ -136,7 +134,7 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { break; } -#undef MAXWELL3D_REG_INDEX + VideoCore::g_renderer->Rasterizer()->NotifyMaxwellRegisterChanged(method); if (debug_context) { debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr); diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 2b45ffed7..b379d8057 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -20,6 +20,9 @@ namespace Tegra { namespace Engines { +#define MAXWELL3D_REG_INDEX(field_name) \ + (offsetof(Tegra::Engines::Maxwell3D::Regs, field_name) / sizeof(u32)) + class Maxwell3D final { public: explicit Maxwell3D(MemoryManager& memory_manager); @@ -254,6 +257,46 @@ public: UnsignedInt = 0x2, }; + struct Blend { + enum class Equation : u32 { + Add = 1, + Subtract = 2, + ReverseSubtract = 3, + Min = 4, + Max = 5, + }; + + enum class Factor : u32 { + Zero = 0x1, + One = 0x2, + SourceColor = 0x3, + OneMinusSourceColor = 0x4, + SourceAlpha = 0x5, + OneMinusSourceAlpha = 0x6, + DestAlpha = 0x7, + OneMinusDestAlpha = 0x8, + DestColor = 0x9, + OneMinusDestColor = 0xa, + SourceAlphaSaturate = 0xb, + Source1Color = 0x10, + OneMinusSource1Color = 0x11, + Source1Alpha = 0x12, + OneMinusSource1Alpha = 0x13, + ConstantColor = 0x61, + OneMinusConstantColor = 0x62, + ConstantAlpha = 0x63, + OneMinusConstantAlpha = 0x64, + }; + + u32 separate_alpha; + Equation equation_rgb; + Factor factor_source_rgb; + Factor factor_dest_rgb; + Equation equation_a; + Factor factor_source_a; + Factor factor_dest_a; + }; + union { struct { INSERT_PADDING_WORDS(0x200); @@ -451,7 +494,9 @@ public: } } vertex_array[NumVertexArrays]; - INSERT_PADDING_WORDS(0x40); + Blend blend; + + INSERT_PADDING_WORDS(0x39); struct { u32 limit_high; @@ -616,6 +661,7 @@ ASSERT_REG_POSITION(draw, 0x585); ASSERT_REG_POSITION(index_array, 0x5F2); ASSERT_REG_POSITION(query, 0x6C0); ASSERT_REG_POSITION(vertex_array[0], 0x700); +ASSERT_REG_POSITION(blend, 0x780); ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0); ASSERT_REG_POSITION(shader_config[0], 0x800); ASSERT_REG_POSITION(const_buffer, 0x8E0); diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 35d262189..36629dd11 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -19,7 +19,7 @@ public: virtual void DrawArrays() = 0; /// Notify rasterizer that the specified Maxwell register has been changed - virtual void NotifyMaxwellRegisterChanged(u32 id) = 0; + virtual void NotifyMaxwellRegisterChanged(u32 method) = 0; /// Notify rasterizer that all caches should be flushed to Switch memory virtual void FlushAll() = 0; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 75b4031a7..7b6240e65 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -446,7 +446,32 @@ void RasterizerOpenGL::BindTextures() { } } -void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 id) {} +void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 method) { + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + switch (method) { + case MAXWELL3D_REG_INDEX(blend.separate_alpha): + ASSERT_MSG(false, "unimplemented"); + break; + case MAXWELL3D_REG_INDEX(blend.equation_rgb): + state.blend.rgb_equation = MaxwellToGL::BlendEquation(regs.blend.equation_rgb); + break; + case MAXWELL3D_REG_INDEX(blend.factor_source_rgb): + state.blend.src_rgb_func = MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb); + break; + case MAXWELL3D_REG_INDEX(blend.factor_dest_rgb): + state.blend.dst_rgb_func = MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb); + break; + case MAXWELL3D_REG_INDEX(blend.equation_a): + state.blend.a_equation = MaxwellToGL::BlendEquation(regs.blend.equation_a); + break; + case MAXWELL3D_REG_INDEX(blend.factor_source_a): + state.blend.src_a_func = MaxwellToGL::BlendFunc(regs.blend.factor_source_a); + break; + case MAXWELL3D_REG_INDEX(blend.factor_dest_a): + state.blend.dst_a_func = MaxwellToGL::BlendFunc(regs.blend.factor_dest_a); + break; + } +} void RasterizerOpenGL::FlushAll() { MICROPROFILE_SCOPE(OpenGL_CacheManagement); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index fb5d99ba2..9ece415f7 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -32,7 +32,7 @@ public: ~RasterizerOpenGL() override; void DrawArrays() override; - void NotifyMaxwellRegisterChanged(u32 id) override; + void NotifyMaxwellRegisterChanged(u32 method) override; void FlushAll() override; void FlushRegion(VAddr addr, u64 size) override; void InvalidateRegion(VAddr addr, u64 size) override; diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index aa5026cce..a49265b38 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -102,4 +102,68 @@ inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) { return {}; } +inline GLenum BlendEquation(Maxwell::Blend::Equation equation) { + switch (equation) { + case Maxwell::Blend::Equation::Add: + return GL_FUNC_ADD; + case Maxwell::Blend::Equation::Subtract: + return GL_FUNC_SUBTRACT; + case Maxwell::Blend::Equation::ReverseSubtract: + return GL_FUNC_REVERSE_SUBTRACT; + case Maxwell::Blend::Equation::Min: + return GL_MIN; + case Maxwell::Blend::Equation::Max: + return GL_MAX; + } + NGLOG_CRITICAL(Render_OpenGL, "Unimplemented blend equation={}", static_cast(equation)); + UNREACHABLE(); + return {}; +} + +inline GLenum BlendFunc(Maxwell::Blend::Factor factor) { + switch (factor) { + case Maxwell::Blend::Factor::Zero: + return GL_ZERO; + case Maxwell::Blend::Factor::One: + return GL_ONE; + case Maxwell::Blend::Factor::SourceColor: + return GL_SRC_COLOR; + case Maxwell::Blend::Factor::OneMinusSourceColor: + return GL_ONE_MINUS_SRC_COLOR; + case Maxwell::Blend::Factor::SourceAlpha: + return GL_SRC_ALPHA; + case Maxwell::Blend::Factor::OneMinusSourceAlpha: + return GL_ONE_MINUS_SRC_ALPHA; + case Maxwell::Blend::Factor::DestAlpha: + return GL_DST_ALPHA; + case Maxwell::Blend::Factor::OneMinusDestAlpha: + return GL_ONE_MINUS_DST_ALPHA; + case Maxwell::Blend::Factor::DestColor: + return GL_DST_COLOR; + case Maxwell::Blend::Factor::OneMinusDestColor: + return GL_ONE_MINUS_DST_COLOR; + case Maxwell::Blend::Factor::SourceAlphaSaturate: + return GL_SRC_ALPHA_SATURATE; + case Maxwell::Blend::Factor::Source1Color: + return GL_SRC1_COLOR; + case Maxwell::Blend::Factor::OneMinusSource1Color: + return GL_ONE_MINUS_SRC1_COLOR; + case Maxwell::Blend::Factor::Source1Alpha: + return GL_SRC1_ALPHA; + case Maxwell::Blend::Factor::OneMinusSource1Alpha: + return GL_ONE_MINUS_SRC1_ALPHA; + case Maxwell::Blend::Factor::ConstantColor: + return GL_CONSTANT_COLOR; + case Maxwell::Blend::Factor::OneMinusConstantColor: + return GL_ONE_MINUS_CONSTANT_COLOR; + case Maxwell::Blend::Factor::ConstantAlpha: + return GL_CONSTANT_ALPHA; + case Maxwell::Blend::Factor::OneMinusConstantAlpha: + return GL_ONE_MINUS_CONSTANT_ALPHA; + } + NGLOG_CRITICAL(Render_OpenGL, "Unimplemented blend factor={}", static_cast(factor)); + UNREACHABLE(); + return {}; +} + } // namespace MaxwellToGL -- cgit v1.2.3