diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 28 | 
6 files changed, 59 insertions, 3 deletions
| diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index c8af1c6b6..0e09a7ee5 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -643,8 +643,10 @@ public:                  u32 d3d_cull_mode;                  ComparisonOp depth_test_func; +                float alpha_test_ref; +                ComparisonOp alpha_test_func; -                INSERT_PADDING_WORDS(0xB); +                INSERT_PADDING_WORDS(0x9);                  struct {                      u32 separate_alpha; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 3daccf82f..e2a422052 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -323,6 +323,8 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {          current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader,                                                    primitive_mode, current_texture_bindpoint); +        SetupAlphaTesting(shader); +          // When VertexA is enabled, we have dual vertex shaders          if (program == Maxwell::ShaderProgram::VertexA) {              // VertexB was combined with VertexA, so we skip the VertexB iteration @@ -880,6 +882,15 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,      return current_unit + static_cast<u32>(entries.size());  } +void RasterizerOpenGL::SetupAlphaTesting(Shader& shader) { +    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; + +    glProgramUniform1i(shader->GetProgramHandle(), shader->GetAlphaTestingEnableLocation(), +                       regs.alpha_test_enabled); +    glProgramUniform1f(shader->GetProgramHandle(), shader->GetAlphaTestingRefLocation(), +                       regs.alpha_test_ref); +} +  void RasterizerOpenGL::SyncViewport() {      const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;      const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index b1f7ccc7e..06ba23f48 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -132,6 +132,8 @@ private:      u32 SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader,                        GLenum primitive_mode, u32 current_unit); +    void SetupAlphaTesting(Shader& shader); +      /// Syncs the viewport to match the guest state      void SyncViewport(); diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 1a03a677f..f4e99e5f4 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -134,6 +134,18 @@ GLuint CachedShader::LazyGeometryProgram(OGLProgram& target_program,      return target_program.handle;  }; +GLint CachedShader::GetAlphaTestingEnableLocation() { +    return glGetUniformLocation(program.handle, "alpha_testing_enable"); +} + +GLint CachedShader::GetAlphaTestingFuncLocation() { +    return glGetUniformLocation(program.handle, "alpha_testing_func"); +} + +GLint CachedShader::GetAlphaTestingRefLocation() { +    return glGetUniformLocation(program.handle, "alpha_testing_ref"); +} +  Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {      const VAddr program_addr{GetShaderAddress(program)}; diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index a210f1731..9333f423f 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h @@ -73,6 +73,11 @@ public:      /// Gets the GL uniform location for the specified resource, caching as needed      GLint GetUniformLocation(const GLShader::SamplerEntry& sampler); + +    GLint GetAlphaTestingEnableLocation(); +    GLint GetAlphaTestingFuncLocation(); +    GLint GetAlphaTestingRefLocation(); +  private:      /// Generates a geometry shader or returns one that already exists.      GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology, diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index b0eb879cc..e890cfe57 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -643,6 +643,13 @@ private:                                   ';');          }          declarations.AddNewLine(); + +        if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { +            declarations.AddLine("uniform bool alpha_testing_active;"); +            declarations.AddLine("uniform float alpha_testing_ref;"); +            declarations.AddLine("uniform uint alpha_testing_func;"); +        } +        declarations.AddNewLine();      }      /// Generates declarations used for geometry shaders. @@ -1264,9 +1271,26 @@ private:          ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented"); +        shader.AddLine("if (alpha_testing_active) {"); +        ++shader.scope; +        u32 current_reg = 3; +        for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets; +             ++render_target) { +            if (header.ps.IsColorComponentOutputEnabled(render_target, 0) || +                header.ps.IsColorComponentOutputEnabled(render_target, 1) || +                header.ps.IsColorComponentOutputEnabled(render_target, 2) || +                header.ps.IsColorComponentOutputEnabled(render_target, 3)) { +                shader.AddLine(fmt::format("if ({} < alpha_testing_ref) discard;", +                                           regs.GetRegisterAsFloat(current_reg))); +                current_reg += 4; +            } +        } +        --shader.scope; +        shader.AddLine("}"); +          // Write the color outputs using the data in the shader registers, disabled          // rendertargets/components are skipped in the register assignment. -        u32 current_reg = 0; +        current_reg = 0;          for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets;               ++render_target) {              // TODO(Subv): Figure out how dual-source blending is configured in the Switch. @@ -3497,7 +3521,7 @@ private:      // Declarations      std::set<std::string> declr_predicates; -}; // namespace Decompiler +}; // namespace OpenGL::GLShader::Decompiler  std::string GetCommonDeclarations() {      return fmt::format("#define MAX_CONSTBUFFER_ELEMENTS {}\n", | 
