summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFernandoS27 <fsahmkow27@gmail.com>2018-10-09 05:34:11 +0200
committerFernandoS27 <fsahmkow27@gmail.com>2018-10-22 21:07:30 +0200
commitaa620c14af0a9bc2bf7784ed096298fc3c8899c3 (patch)
tree699de63d8265e2a7a6bc65b136fc9926cedb9e70
parentMerge pull request #1541 from lioncash/define (diff)
downloadyuzu-aa620c14af0a9bc2bf7784ed096298fc3c8899c3.tar
yuzu-aa620c14af0a9bc2bf7784ed096298fc3c8899c3.tar.gz
yuzu-aa620c14af0a9bc2bf7784ed096298fc3c8899c3.tar.bz2
yuzu-aa620c14af0a9bc2bf7784ed096298fc3c8899c3.tar.lz
yuzu-aa620c14af0a9bc2bf7784ed096298fc3c8899c3.tar.xz
yuzu-aa620c14af0a9bc2bf7784ed096298fc3c8899c3.tar.zst
yuzu-aa620c14af0a9bc2bf7784ed096298fc3c8899c3.zip
-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:
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",