diff options
| -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: | |||
| 643 | u32 d3d_cull_mode; | 643 | u32 d3d_cull_mode; |
| 644 | 644 | ||
| 645 | ComparisonOp depth_test_func; | 645 | ComparisonOp depth_test_func; |
| 646 | float alpha_test_ref; | ||
| 647 | ComparisonOp alpha_test_func; | ||
| 646 | 648 | ||
| 647 | INSERT_PADDING_WORDS(0xB); | 649 | INSERT_PADDING_WORDS(0x9); |
| 648 | 650 | ||
| 649 | struct { | 651 | struct { |
| 650 | u32 separate_alpha; | 652 | 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) { | |||
| 323 | current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, | 323 | current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, |
| 324 | primitive_mode, current_texture_bindpoint); | 324 | primitive_mode, current_texture_bindpoint); |
| 325 | 325 | ||
| 326 | SetupAlphaTesting(shader); | ||
| 327 | |||
| 326 | // When VertexA is enabled, we have dual vertex shaders | 328 | // When VertexA is enabled, we have dual vertex shaders |
| 327 | if (program == Maxwell::ShaderProgram::VertexA) { | 329 | if (program == Maxwell::ShaderProgram::VertexA) { |
| 328 | // VertexB was combined with VertexA, so we skip the VertexB iteration | 330 | // VertexB was combined with VertexA, so we skip the VertexB iteration |
| @@ -880,6 +882,15 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, | |||
| 880 | return current_unit + static_cast<u32>(entries.size()); | 882 | return current_unit + static_cast<u32>(entries.size()); |
| 881 | } | 883 | } |
| 882 | 884 | ||
| 885 | void RasterizerOpenGL::SetupAlphaTesting(Shader& shader) { | ||
| 886 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | ||
| 887 | |||
| 888 | glProgramUniform1i(shader->GetProgramHandle(), shader->GetAlphaTestingEnableLocation(), | ||
| 889 | regs.alpha_test_enabled); | ||
| 890 | glProgramUniform1f(shader->GetProgramHandle(), shader->GetAlphaTestingRefLocation(), | ||
| 891 | regs.alpha_test_ref); | ||
| 892 | } | ||
| 893 | |||
| 883 | void RasterizerOpenGL::SyncViewport() { | 894 | void RasterizerOpenGL::SyncViewport() { |
| 884 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 895 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 885 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; | 896 | 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: | |||
| 132 | u32 SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader, | 132 | u32 SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader, |
| 133 | GLenum primitive_mode, u32 current_unit); | 133 | GLenum primitive_mode, u32 current_unit); |
| 134 | 134 | ||
| 135 | void SetupAlphaTesting(Shader& shader); | ||
| 136 | |||
| 135 | /// Syncs the viewport to match the guest state | 137 | /// Syncs the viewport to match the guest state |
| 136 | void SyncViewport(); | 138 | void SyncViewport(); |
| 137 | 139 | ||
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, | |||
| 134 | return target_program.handle; | 134 | return target_program.handle; |
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | GLint CachedShader::GetAlphaTestingEnableLocation() { | ||
| 138 | return glGetUniformLocation(program.handle, "alpha_testing_enable"); | ||
| 139 | } | ||
| 140 | |||
| 141 | GLint CachedShader::GetAlphaTestingFuncLocation() { | ||
| 142 | return glGetUniformLocation(program.handle, "alpha_testing_func"); | ||
| 143 | } | ||
| 144 | |||
| 145 | GLint CachedShader::GetAlphaTestingRefLocation() { | ||
| 146 | return glGetUniformLocation(program.handle, "alpha_testing_ref"); | ||
| 147 | } | ||
| 148 | |||
| 137 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { | 149 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { |
| 138 | const VAddr program_addr{GetShaderAddress(program)}; | 150 | const VAddr program_addr{GetShaderAddress(program)}; |
| 139 | 151 | ||
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: | |||
| 73 | /// Gets the GL uniform location for the specified resource, caching as needed | 73 | /// Gets the GL uniform location for the specified resource, caching as needed |
| 74 | GLint GetUniformLocation(const GLShader::SamplerEntry& sampler); | 74 | GLint GetUniformLocation(const GLShader::SamplerEntry& sampler); |
| 75 | 75 | ||
| 76 | |||
| 77 | GLint GetAlphaTestingEnableLocation(); | ||
| 78 | GLint GetAlphaTestingFuncLocation(); | ||
| 79 | GLint GetAlphaTestingRefLocation(); | ||
| 80 | |||
| 76 | private: | 81 | private: |
| 77 | /// Generates a geometry shader or returns one that already exists. | 82 | /// Generates a geometry shader or returns one that already exists. |
| 78 | GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology, | 83 | 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: | |||
| 643 | ';'); | 643 | ';'); |
| 644 | } | 644 | } |
| 645 | declarations.AddNewLine(); | 645 | declarations.AddNewLine(); |
| 646 | |||
| 647 | if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { | ||
| 648 | declarations.AddLine("uniform bool alpha_testing_active;"); | ||
| 649 | declarations.AddLine("uniform float alpha_testing_ref;"); | ||
| 650 | declarations.AddLine("uniform uint alpha_testing_func;"); | ||
| 651 | } | ||
| 652 | declarations.AddNewLine(); | ||
| 646 | } | 653 | } |
| 647 | 654 | ||
| 648 | /// Generates declarations used for geometry shaders. | 655 | /// Generates declarations used for geometry shaders. |
| @@ -1264,9 +1271,26 @@ private: | |||
| 1264 | 1271 | ||
| 1265 | ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented"); | 1272 | ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented"); |
| 1266 | 1273 | ||
| 1274 | shader.AddLine("if (alpha_testing_active) {"); | ||
| 1275 | ++shader.scope; | ||
| 1276 | u32 current_reg = 3; | ||
| 1277 | for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets; | ||
| 1278 | ++render_target) { | ||
| 1279 | if (header.ps.IsColorComponentOutputEnabled(render_target, 0) || | ||
| 1280 | header.ps.IsColorComponentOutputEnabled(render_target, 1) || | ||
| 1281 | header.ps.IsColorComponentOutputEnabled(render_target, 2) || | ||
| 1282 | header.ps.IsColorComponentOutputEnabled(render_target, 3)) { | ||
| 1283 | shader.AddLine(fmt::format("if ({} < alpha_testing_ref) discard;", | ||
| 1284 | regs.GetRegisterAsFloat(current_reg))); | ||
| 1285 | current_reg += 4; | ||
| 1286 | } | ||
| 1287 | } | ||
| 1288 | --shader.scope; | ||
| 1289 | shader.AddLine("}"); | ||
| 1290 | |||
| 1267 | // Write the color outputs using the data in the shader registers, disabled | 1291 | // Write the color outputs using the data in the shader registers, disabled |
| 1268 | // rendertargets/components are skipped in the register assignment. | 1292 | // rendertargets/components are skipped in the register assignment. |
| 1269 | u32 current_reg = 0; | 1293 | current_reg = 0; |
| 1270 | for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets; | 1294 | for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets; |
| 1271 | ++render_target) { | 1295 | ++render_target) { |
| 1272 | // TODO(Subv): Figure out how dual-source blending is configured in the Switch. | 1296 | // TODO(Subv): Figure out how dual-source blending is configured in the Switch. |
| @@ -3497,7 +3521,7 @@ private: | |||
| 3497 | 3521 | ||
| 3498 | // Declarations | 3522 | // Declarations |
| 3499 | std::set<std::string> declr_predicates; | 3523 | std::set<std::string> declr_predicates; |
| 3500 | }; // namespace Decompiler | 3524 | }; // namespace OpenGL::GLShader::Decompiler |
| 3501 | 3525 | ||
| 3502 | std::string GetCommonDeclarations() { | 3526 | std::string GetCommonDeclarations() { |
| 3503 | return fmt::format("#define MAX_CONSTBUFFER_ELEMENTS {}\n", | 3527 | return fmt::format("#define MAX_CONSTBUFFER_ELEMENTS {}\n", |