From 38f35df7b6510cbe1c15694d3d4053c803ce9fd3 Mon Sep 17 00:00:00 2001 From: raven02 Date: Mon, 26 Sep 2016 18:38:52 +0800 Subject: [PATCH] DX12: enable alpha kill (#2158) --- .../D3D12/D3D12FragmentProgramDecompiler.cpp | 60 +++++++++++++------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp index 6e2b260a41..6c9e820dc1 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp @@ -172,6 +172,21 @@ namespace return; } } + + std::string insert_texture_fetch(const RSXFragmentProgram& prog, int index) + { + std::string tex_name = "tex" + std::to_string(index) + ".Sample"; + std::string sampler_name = "tex" + std::to_string(index) + "sampler"; + std::string coord_name = "In.tc" + std::to_string(index); + + switch (prog.get_texture_dimension(index)) + { + case rsx::texture_dimension_extended::texture_dimension_1d: return " " + tex_name + " (" + sampler_name + ", " + coord_name + ".x) "; + case rsx::texture_dimension_extended::texture_dimension_2d: return " " + tex_name + " (" + sampler_name + ", " + coord_name + ".xy) "; + case rsx::texture_dimension_extended::texture_dimension_3d: + case rsx::texture_dimension_extended::texture_dimension_cubemap: return " " + tex_name + " (" + sampler_name + ", " + coord_name + ".xyz) "; + } + } } void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS) @@ -296,27 +311,34 @@ void D3D12FragmentDecompiler::insertMainEnd(std::stringstream & OS) // Shaders don't always output colors (for instance if they write to depth only) if (!first_output_name.empty()) { - switch (m_prog.alpha_func) + auto make_comparison_test = [](rsx::comparison_function compare_func, const std::string &test, const std::string &a, const std::string &b) -> std::string { - case rsx::comparison_function::equal: - OS << " if (isAlphaTested && Out." << first_output_name << ".a != alphaRef) discard;\n"; - break; - case rsx::comparison_function::not_equal: - OS << " if (isAlphaTested && Out." << first_output_name << ".a == alphaRef) discard;\n"; - break; - case rsx::comparison_function::less_or_equal: - OS << " if (isAlphaTested && Out." << first_output_name << ".a > alphaRef) discard;\n"; - break; - case rsx::comparison_function::less: - OS << " if (isAlphaTested && Out." << first_output_name << ".a >= alphaRef) discard;\n"; - break; - case rsx::comparison_function::greater: - OS << " if (isAlphaTested && Out." << first_output_name << ".a <= alphaRef) discard;\n"; - break; - case rsx::comparison_function::greater_or_equal: - OS << " if (isAlphaTested && Out." << first_output_name << ".a < alphaRef) discard;\n"; - break; + std::string compare; + switch (compare_func) + { + case rsx::comparison_function::equal: compare = " == "; break; + case rsx::comparison_function::not_equal: compare = " != "; break; + case rsx::comparison_function::less_or_equal: compare = " <= "; break; + case rsx::comparison_function::less: compare = " < "; break; + case rsx::comparison_function::greater: compare = " > "; break; + case rsx::comparison_function::greater_or_equal: compare = " >= "; break; + default: + return ""; + } + + return " if (" + test + "!(" + a + compare + b + ")) discard;\n"; + }; + + for (u8 index = 0; index < 16; ++index) + { + if (m_prog.textures_alpha_kill[index]) + { + std::string fetch_texture = insert_texture_fetch(m_prog, index) + ".a"; + OS << make_comparison_test((rsx::comparison_function)m_prog.textures_zfunc[index], "", "0", fetch_texture); + } } + + OS << make_comparison_test(m_prog.alpha_func, "isAlphaTested && ", "Out." + first_output_name + ".a", "alphaRef"); } OS << " return Out;" << std::endl;