From 1881e86c434edfc17f78f68f07443bef1120cda1 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Tue, 13 Nov 2018 20:13:16 -0300 Subject: fix viewport and scissor behavior --- src/video_core/engines/maxwell_3d.cpp | 4 ++-- src/video_core/engines/maxwell_3d.h | 26 ++++++++++++++++---------- 2 files changed, 18 insertions(+), 12 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 6de07ea56..58b598c7f 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -34,8 +34,8 @@ void Maxwell3D::InitializeRegisterDefaults() { // Depth range near/far is not always set, but is expected to be the default 0.0f, 1.0f. This is // needed for ARMS. for (std::size_t viewport{}; viewport < Regs::NumViewports; ++viewport) { - regs.viewport[viewport].depth_range_near = 0.0f; - regs.viewport[viewport].depth_range_far = 1.0f; + regs.viewports[viewport].depth_range_near = 0.0f; + regs.viewports[viewport].depth_range_far = 1.0f; } // Doom and Bomberman seems to use the uninitialized registers and just enable blend // so initialize blend registers with sane values diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 91ca57883..32780fa9a 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -505,9 +505,9 @@ public: INSERT_PADDING_WORDS(0x2E); - RenderTargetConfig rt[NumRenderTargets]; + std::array rt; - struct { + struct ViewportTransform { f32 scale_x; f32 scale_y; f32 scale_z; @@ -540,9 +540,11 @@ public: s32 GetHeight() const { return static_cast(translate_y + std::fabs(scale_y)) - GetY(); } - } viewport_transform[NumViewports]; + }; - struct { + std::array viewport_transform; + + struct ViewPort { union { BitField<0, 16, u32> x; BitField<16, 16, u32> width; @@ -553,7 +555,9 @@ public: }; float depth_range_near; float depth_range_far; - } viewport[NumViewports]; + }; + + std::array viewports; INSERT_PADDING_WORDS(0x1D); @@ -571,7 +575,7 @@ public: INSERT_PADDING_WORDS(0x17); - struct { + struct ScissorTest { u32 enable; union { BitField<0, 16, u32> min_x; @@ -581,9 +585,11 @@ public: BitField<0, 16, u32> min_y; BitField<16, 16, u32> max_y; }; - } scissor_test; + u32 fill; + }; + std::array scissor_test; - INSERT_PADDING_WORDS(0x52); + INSERT_PADDING_WORDS(0x15); s32 stencil_back_func_ref; u32 stencil_back_mask; @@ -1100,8 +1106,8 @@ private: ASSERT_REG_POSITION(macros, 0x45); ASSERT_REG_POSITION(tfb_enabled, 0x1D1); ASSERT_REG_POSITION(rt, 0x200); -ASSERT_REG_POSITION(viewport_transform[0], 0x280); -ASSERT_REG_POSITION(viewport, 0x300); +ASSERT_REG_POSITION(viewport_transform, 0x280); +ASSERT_REG_POSITION(viewports, 0x300); ASSERT_REG_POSITION(vertex_buffer, 0x35D); ASSERT_REG_POSITION(clear_color[0], 0x360); ASSERT_REG_POSITION(clear_depth, 0x364); -- cgit v1.2.3 From 6a2aa6dbdbe50abe8447db4e9d93dacecf39f269 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Tue, 13 Nov 2018 20:15:13 -0300 Subject: set default value for point size register --- src/video_core/engines/maxwell_3d.cpp | 3 +++ src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 +----- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 58b598c7f..a04e00ecb 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -66,6 +66,9 @@ void Maxwell3D::InitializeRegisterDefaults() { regs.stencil_back_func_func = Regs::ComparisonOp::Always; regs.stencil_back_func_mask = 0xFFFFFFFF; regs.stencil_back_mask = 0xFFFFFFFF; + // TODO(Rodrigo): Most games do not set a point size. I think this is a case of a + // register carrying a default value. Assume it's OpenGL's default (1). + regs.point_size = 1.0f; } void Maxwell3D::CallMacroMethod(u32 method, std::vector parameters) { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 0bf434b45..0e55bee11 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1119,11 +1119,7 @@ void RasterizerOpenGL::SyncTransformFeedback() { void RasterizerOpenGL::SyncPointState() { const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; - - // TODO(Rodrigo): Most games do not set a point size. I think this is a case of a - // register carrying a default value. For now, if the point size is zero, assume it's - // OpenGL's default (1). - state.point.size = regs.point_size == 0 ? 1 : regs.point_size; + state.point.size = regs.point_size; } void RasterizerOpenGL::CheckAlphaTests() { -- cgit v1.2.3 From 8ed7e1af2c8d859ca5e1bd05e199b1f14099c8b4 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Tue, 13 Nov 2018 22:09:01 -0300 Subject: add support for fragment_color_clamp --- src/video_core/engines/maxwell_3d.h | 5 ++++- src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 ++++++ src/video_core/renderer_opengl/gl_rasterizer.h | 3 +++ src/video_core/renderer_opengl/gl_state.cpp | 7 +++++++ src/video_core/renderer_opengl/gl_state.h | 4 ++++ 5 files changed, 24 insertions(+), 1 deletion(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 32780fa9a..f2d69814e 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -706,7 +706,9 @@ public: u32 stencil_front_func_mask; u32 stencil_front_mask; - INSERT_PADDING_WORDS(0x3); + INSERT_PADDING_WORDS(0x2); + + u32 frag_color_clamp; union { BitField<4, 1, u32> triangle_rast_flip; @@ -1142,6 +1144,7 @@ ASSERT_REG_POSITION(stencil_front_func_func, 0x4E4); ASSERT_REG_POSITION(stencil_front_func_ref, 0x4E5); ASSERT_REG_POSITION(stencil_front_func_mask, 0x4E6); ASSERT_REG_POSITION(stencil_front_mask, 0x4E7); +ASSERT_REG_POSITION(frag_color_clamp, 0x4EA); ASSERT_REG_POSITION(screen_y_control, 0x4EB); ASSERT_REG_POSITION(vb_element_base, 0x50D); ASSERT_REG_POSITION(point_size, 0x546); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 10d407bd2..98799056c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -582,6 +582,7 @@ void RasterizerOpenGL::DrawArrays() { ConfigureFramebuffers(state); SyncColorMask(); + SyncFragmentColorClampState(); SyncDepthTestState(); SyncStencilTestState(); SyncBlendState(); @@ -1032,6 +1033,11 @@ void RasterizerOpenGL::SyncColorMask() { } } +void RasterizerOpenGL::SyncFragmentColorClampState() { + const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; + state.fragment_color_clamp.enabled = regs.frag_color_clamp != 0; +} + void RasterizerOpenGL::SyncBlendState() { const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 8ef0f6c12..d3fa0b6fc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -160,6 +160,9 @@ private: /// Syncs the LogicOp state to match the guest state void SyncLogicOpState(); + /// Syncs the the color clamp state + void SyncFragmentColorClampState(); + /// Syncs the scissor test state to match the guest state void SyncScissorTest(); diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index dd6d946e5..6998dd92b 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -89,6 +89,7 @@ OpenGLState::OpenGLState() { clip_distance = {}; point.size = 1; + fragment_color_clamp.enabled = false; } void OpenGLState::ApplyDefaultState() { @@ -497,6 +498,12 @@ void OpenGLState::Apply() const { if (point.size != cur_state.point.size) { glPointSize(point.size); } + if (GLAD_GL_ARB_color_buffer_float) { + if (fragment_color_clamp.enabled != cur_state.fragment_color_clamp.enabled) { + glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, + fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE); + } + } ApplyColorMask(); ApplyViewport(); ApplyStencilTest(); diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index da487461f..6079f6e0b 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -39,6 +39,10 @@ public: bool enabled; // GL_FRAMEBUFFER_SRGB } framebuffer_srgb; + struct { + bool enabled; // GL_CLAMP_FRAGMENT_COLOR_ARB + } fragment_color_clamp; + struct { bool enabled; // viewports arrays are only supported when geometry shaders are enabled. } geometry_shaders; -- cgit v1.2.3 From 53b4a1af0f8a8c1e7c0ad27c76adf3b0e86bef13 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Wed, 14 Nov 2018 00:02:54 -0300 Subject: add AlphaToCoverage and AlphaToOne --- src/video_core/engines/maxwell_3d.h | 8 +++++++- src/video_core/renderer_opengl/gl_rasterizer.cpp | 7 +++++++ src/video_core/renderer_opengl/gl_rasterizer.h | 3 +++ src/video_core/renderer_opengl/gl_state.cpp | 17 +++++++++++++++++ src/video_core/renderer_opengl/gl_state.h | 5 +++++ 5 files changed, 39 insertions(+), 1 deletion(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index f2d69814e..753aff57f 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -726,7 +726,12 @@ public: u32 zeta_enable; - INSERT_PADDING_WORDS(0x8); + union { + BitField<1, 1, u32> alpha_to_coverage; + BitField<2, 1, u32> alpha_to_one; + } multisample_control; + + INSERT_PADDING_WORDS(0x7); struct { u32 tsc_address_high; @@ -1149,6 +1154,7 @@ ASSERT_REG_POSITION(screen_y_control, 0x4EB); ASSERT_REG_POSITION(vb_element_base, 0x50D); ASSERT_REG_POSITION(point_size, 0x546); ASSERT_REG_POSITION(zeta_enable, 0x54E); +ASSERT_REG_POSITION(multisample_control, 0x54F); ASSERT_REG_POSITION(tsc, 0x557); ASSERT_REG_POSITION(tic, 0x55D); ASSERT_REG_POSITION(stencil_two_side_enable, 0x565); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 98799056c..d2e3fde65 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -583,6 +583,7 @@ void RasterizerOpenGL::DrawArrays() { ConfigureFramebuffers(state); SyncColorMask(); SyncFragmentColorClampState(); + SyncMultiSampleState(); SyncDepthTestState(); SyncStencilTestState(); SyncBlendState(); @@ -1033,6 +1034,12 @@ void RasterizerOpenGL::SyncColorMask() { } } +void RasterizerOpenGL::SyncMultiSampleState() { + const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; + state.multisample_control.alpha_to_coverage = regs.multisample_control.alpha_to_coverage != 0; + state.multisample_control.alpha_to_one = regs.multisample_control.alpha_to_one != 0; +} + void RasterizerOpenGL::SyncFragmentColorClampState() { const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; state.fragment_color_clamp.enabled = regs.frag_color_clamp != 0; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index d3fa0b6fc..8994e134a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -163,6 +163,9 @@ private: /// Syncs the the color clamp state void SyncFragmentColorClampState(); + /// Syncs the alpha coverage and alpha to one + void SyncMultiSampleState(); + /// Syncs the scissor test state to match the guest state void SyncScissorTest(); diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 6998dd92b..f6d80614b 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -16,6 +16,8 @@ OpenGLState::OpenGLState() { // These all match default OpenGL values geometry_shaders.enabled = false; framebuffer_srgb.enabled = false; + multisample_control.alpha_to_coverage = false; + multisample_control.alpha_to_one = false; cull.enabled = false; cull.mode = GL_BACK; cull.front_face = GL_CCW; @@ -504,6 +506,21 @@ void OpenGLState::Apply() const { fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE); } } + if (multisample_control.alpha_to_coverage != cur_state.multisample_control.alpha_to_coverage) { + if (multisample_control.alpha_to_coverage) { + glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); + } else { + glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); + } + } + if (multisample_control.alpha_to_one != cur_state.multisample_control.alpha_to_one) { + if (multisample_control.alpha_to_one) { + glEnable(GL_SAMPLE_ALPHA_TO_ONE); + } else { + glDisable(GL_SAMPLE_ALPHA_TO_ONE); + } + } + ApplyColorMask(); ApplyViewport(); ApplyStencilTest(); diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 6079f6e0b..c8d951a7f 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -39,6 +39,11 @@ public: bool enabled; // GL_FRAMEBUFFER_SRGB } framebuffer_srgb; + struct { + bool alpha_to_coverage; // GL_ALPHA_TO_COVERAGE + bool alpha_to_one; // GL_ALPHA_TO_ONE + } multisample_control; + struct { bool enabled; // GL_CLAMP_FRAGMENT_COLOR_ARB } fragment_color_clamp; -- cgit v1.2.3 From e69eb3c7609bdb632e4c3e979562325b7a0b4610 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Wed, 14 Nov 2018 14:34:02 -0300 Subject: fix for gcc compilation --- src/video_core/engines/maxwell_3d.h | 121 ++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 60 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 753aff57f..1af948d24 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -480,6 +480,67 @@ public: }; }; + struct ViewportTransform { + f32 scale_x; + f32 scale_y; + f32 scale_z; + f32 translate_x; + f32 translate_y; + f32 translate_z; + INSERT_PADDING_WORDS(2); + + MathUtil::Rectangle GetRect() const { + return { + GetX(), // left + GetY() + GetHeight(), // top + GetX() + GetWidth(), // right + GetY() // bottom + }; + }; + + s32 GetX() const { + return static_cast(std::max(0.0f, translate_x - std::fabs(scale_x))); + } + + s32 GetY() const { + return static_cast(std::max(0.0f, translate_y - std::fabs(scale_y))); + } + + s32 GetWidth() const { + return static_cast(translate_x + std::fabs(scale_x)) - GetX(); + } + + s32 GetHeight() const { + return static_cast(translate_y + std::fabs(scale_y)) - GetY(); + } + }; + + struct ScissorTest { + u32 enable; + union { + BitField<0, 16, u32> min_x; + BitField<16, 16, u32> max_x; + }; + union { + BitField<0, 16, u32> min_y; + BitField<16, 16, u32> max_y; + }; + u32 fill; + }; + + struct ViewPort { + union { + BitField<0, 16, u32> x; + BitField<16, 16, u32> width; + }; + union { + BitField<0, 16, u32> y; + BitField<16, 16, u32> height; + }; + float depth_range_near; + float depth_range_far; + }; + bool IsShaderConfigEnabled(std::size_t index) const { // The VertexB is always enabled. if (index == static_cast(Regs::ShaderProgram::VertexB)) { @@ -507,56 +568,8 @@ public: std::array rt; - struct ViewportTransform { - f32 scale_x; - f32 scale_y; - f32 scale_z; - f32 translate_x; - f32 translate_y; - f32 translate_z; - INSERT_PADDING_WORDS(2); - - MathUtil::Rectangle GetRect() const { - return { - GetX(), // left - GetY() + GetHeight(), // top - GetX() + GetWidth(), // right - GetY() // bottom - }; - }; - - s32 GetX() const { - return static_cast(std::max(0.0f, translate_x - std::fabs(scale_x))); - } - - s32 GetY() const { - return static_cast(std::max(0.0f, translate_y - std::fabs(scale_y))); - } - - s32 GetWidth() const { - return static_cast(translate_x + std::fabs(scale_x)) - GetX(); - } - - s32 GetHeight() const { - return static_cast(translate_y + std::fabs(scale_y)) - GetY(); - } - }; - std::array viewport_transform; - struct ViewPort { - union { - BitField<0, 16, u32> x; - BitField<16, 16, u32> width; - }; - union { - BitField<0, 16, u32> y; - BitField<16, 16, u32> height; - }; - float depth_range_near; - float depth_range_far; - }; - std::array viewports; INSERT_PADDING_WORDS(0x1D); @@ -575,18 +588,6 @@ public: INSERT_PADDING_WORDS(0x17); - struct ScissorTest { - u32 enable; - union { - BitField<0, 16, u32> min_x; - BitField<16, 16, u32> max_x; - }; - union { - BitField<0, 16, u32> min_y; - BitField<16, 16, u32> max_y; - }; - u32 fill; - }; std::array scissor_test; INSERT_PADDING_WORDS(0x15); -- cgit v1.2.3 From 5297495c871b7907f1ad03b4ef24f60e2c08daca Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Wed, 14 Nov 2018 17:31:47 -0300 Subject: small fix for alphaToOne bit location --- src/video_core/engines/maxwell_3d.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 1af948d24..9e480dc39 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -728,8 +728,8 @@ public: u32 zeta_enable; union { - BitField<1, 1, u32> alpha_to_coverage; - BitField<2, 1, u32> alpha_to_one; + BitField<0, 1, u32> alpha_to_coverage; + BitField<4, 1, u32> alpha_to_one; } multisample_control; INSERT_PADDING_WORDS(0x7); -- cgit v1.2.3