Implemented Alpha Testing
This commit is contained in:
parent
65df593951
commit
aa620c14af
|
@ -643,8 +643,10 @@ public:
|
||||||
u32 d3d_cull_mode;
|
u32 d3d_cull_mode;
|
||||||
|
|
||||||
ComparisonOp depth_test_func;
|
ComparisonOp depth_test_func;
|
||||||
|
float alpha_test_ref;
|
||||||
|
ComparisonOp alpha_test_func;
|
||||||
|
|
||||||
INSERT_PADDING_WORDS(0xB);
|
INSERT_PADDING_WORDS(0x9);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u32 separate_alpha;
|
u32 separate_alpha;
|
||||||
|
|
|
@ -323,6 +323,8 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
|
||||||
current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader,
|
current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader,
|
||||||
primitive_mode, current_texture_bindpoint);
|
primitive_mode, current_texture_bindpoint);
|
||||||
|
|
||||||
|
SetupAlphaTesting(shader);
|
||||||
|
|
||||||
// When VertexA is enabled, we have dual vertex shaders
|
// When VertexA is enabled, we have dual vertex shaders
|
||||||
if (program == Maxwell::ShaderProgram::VertexA) {
|
if (program == Maxwell::ShaderProgram::VertexA) {
|
||||||
// VertexB was combined with VertexA, so we skip the VertexB iteration
|
// 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());
|
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() {
|
void RasterizerOpenGL::SyncViewport() {
|
||||||
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
|
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
|
||||||
const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
|
const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
|
||||||
|
|
|
@ -132,6 +132,8 @@ private:
|
||||||
u32 SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader,
|
u32 SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader,
|
||||||
GLenum primitive_mode, u32 current_unit);
|
GLenum primitive_mode, u32 current_unit);
|
||||||
|
|
||||||
|
void SetupAlphaTesting(Shader& shader);
|
||||||
|
|
||||||
/// Syncs the viewport to match the guest state
|
/// Syncs the viewport to match the guest state
|
||||||
void SyncViewport();
|
void SyncViewport();
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,18 @@ GLuint CachedShader::LazyGeometryProgram(OGLProgram& target_program,
|
||||||
return target_program.handle;
|
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) {
|
Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
|
||||||
const VAddr program_addr{GetShaderAddress(program)};
|
const VAddr program_addr{GetShaderAddress(program)};
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,11 @@ public:
|
||||||
/// Gets the GL uniform location for the specified resource, caching as needed
|
/// Gets the GL uniform location for the specified resource, caching as needed
|
||||||
GLint GetUniformLocation(const GLShader::SamplerEntry& sampler);
|
GLint GetUniformLocation(const GLShader::SamplerEntry& sampler);
|
||||||
|
|
||||||
|
|
||||||
|
GLint GetAlphaTestingEnableLocation();
|
||||||
|
GLint GetAlphaTestingFuncLocation();
|
||||||
|
GLint GetAlphaTestingRefLocation();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Generates a geometry shader or returns one that already exists.
|
/// Generates a geometry shader or returns one that already exists.
|
||||||
GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology,
|
GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology,
|
||||||
|
|
|
@ -643,6 +643,13 @@ private:
|
||||||
';');
|
';');
|
||||||
}
|
}
|
||||||
declarations.AddNewLine();
|
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.
|
/// Generates declarations used for geometry shaders.
|
||||||
|
@ -1264,9 +1271,26 @@ private:
|
||||||
|
|
||||||
ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented");
|
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
|
// Write the color outputs using the data in the shader registers, disabled
|
||||||
// rendertargets/components are skipped in the register assignment.
|
// 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;
|
for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets;
|
||||||
++render_target) {
|
++render_target) {
|
||||||
// TODO(Subv): Figure out how dual-source blending is configured in the Switch.
|
// TODO(Subv): Figure out how dual-source blending is configured in the Switch.
|
||||||
|
@ -3497,7 +3521,7 @@ private:
|
||||||
|
|
||||||
// Declarations
|
// Declarations
|
||||||
std::set<std::string> declr_predicates;
|
std::set<std::string> declr_predicates;
|
||||||
}; // namespace Decompiler
|
}; // namespace OpenGL::GLShader::Decompiler
|
||||||
|
|
||||||
std::string GetCommonDeclarations() {
|
std::string GetCommonDeclarations() {
|
||||||
return fmt::format("#define MAX_CONSTBUFFER_ELEMENTS {}\n",
|
return fmt::format("#define MAX_CONSTBUFFER_ELEMENTS {}\n",
|
||||||
|
|
Reference in New Issue