summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/maxwell_3d.h4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp12
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp28
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
885void 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
883void RasterizerOpenGL::SyncViewport() { 894void 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
137GLint CachedShader::GetAlphaTestingEnableLocation() {
138 return glGetUniformLocation(program.handle, "alpha_testing_enable");
139}
140
141GLint CachedShader::GetAlphaTestingFuncLocation() {
142 return glGetUniformLocation(program.handle, "alpha_testing_func");
143}
144
145GLint CachedShader::GetAlphaTestingRefLocation() {
146 return glGetUniformLocation(program.handle, "alpha_testing_ref");
147}
148
137Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { 149Shader 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
76private: 81private:
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
3502std::string GetCommonDeclarations() { 3526std::string GetCommonDeclarations() {
3503 return fmt::format("#define MAX_CONSTBUFFER_ELEMENTS {}\n", 3527 return fmt::format("#define MAX_CONSTBUFFER_ELEMENTS {}\n",