diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 70 |
1 files changed, 48 insertions, 22 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 160329f19..3a7e82beb 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -2676,14 +2676,29 @@ private: | |||
| 2676 | const bool depth_compare = | 2676 | const bool depth_compare = |
| 2677 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2677 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| 2678 | u32 num_coordinates = TextureCoordinates(texture_type); | 2678 | u32 num_coordinates = TextureCoordinates(texture_type); |
| 2679 | if (depth_compare) | 2679 | auto process_mode = instr.texs.GetTextureProcessMode(); |
| 2680 | num_coordinates += 1; | 2680 | std::string lod_value; |
| 2681 | u32 lod_offset = 0; | ||
| 2682 | if (process_mode == Tegra::Shader::TextureProcessMode::LL) { | ||
| 2683 | if (num_coordinates > 2) { | ||
| 2684 | lod_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||
| 2685 | lod_offset = 2; | ||
| 2686 | } else { | ||
| 2687 | lod_value = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2688 | lod_offset = 1; | ||
| 2689 | } | ||
| 2690 | } | ||
| 2681 | 2691 | ||
| 2682 | // Scope to avoid variable name overlaps. | 2692 | // Scope to avoid variable name overlaps. |
| 2683 | shader.AddLine('{'); | 2693 | shader.AddLine('{'); |
| 2684 | ++shader.scope; | 2694 | ++shader.scope; |
| 2685 | 2695 | ||
| 2686 | switch (num_coordinates) { | 2696 | switch (num_coordinates) { |
| 2697 | case 1: { | ||
| 2698 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2699 | coord = "float coords = " + x + ';'; | ||
| 2700 | break; | ||
| 2701 | } | ||
| 2687 | case 2: { | 2702 | case 2: { |
| 2688 | if (is_array) { | 2703 | if (is_array) { |
| 2689 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2704 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |
| @@ -2691,26 +2706,37 @@ private: | |||
| 2691 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2706 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2692 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"); | 2707 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"); |
| 2693 | } else { | 2708 | } else { |
| 2694 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2709 | if (lod_offset != 0) { |
| 2695 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2710 | if (depth_compare) { |
| 2696 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); | 2711 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2712 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2713 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset); | ||
| 2714 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||
| 2715 | } else { | ||
| 2716 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2717 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2718 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2719 | } | ||
| 2720 | } else { | ||
| 2721 | if (depth_compare) { | ||
| 2722 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2723 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2724 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2725 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||
| 2726 | } else { | ||
| 2727 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2728 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2729 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2730 | } | ||
| 2731 | } | ||
| 2697 | } | 2732 | } |
| 2698 | break; | 2733 | break; |
| 2699 | } | 2734 | } |
| 2700 | case 3: { | 2735 | case 3: { |
| 2701 | if (is_array) { | 2736 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2702 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2737 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2703 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2738 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |
| 2704 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); | 2739 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; |
| 2705 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2706 | shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + | ||
| 2707 | index + ");"); | ||
| 2708 | } else { | ||
| 2709 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2710 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2711 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2712 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"); | ||
| 2713 | } | ||
| 2714 | break; | 2740 | break; |
| 2715 | } | 2741 | } |
| 2716 | default: | 2742 | default: |
| @@ -2727,22 +2753,22 @@ private: | |||
| 2727 | const std::string sampler = | 2753 | const std::string sampler = |
| 2728 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); | 2754 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); |
| 2729 | std::string texture; | 2755 | std::string texture; |
| 2730 | switch (instr.texs.GetTextureProcessMode()) { | 2756 | switch (process_mode) { |
| 2731 | case Tegra::Shader::TextureProcessMode::None: { | 2757 | case Tegra::Shader::TextureProcessMode::None: { |
| 2732 | texture = "texture(" + sampler + ", coords)"; | 2758 | texture = "texture(" + sampler + ", coords)"; |
| 2733 | break; | 2759 | break; |
| 2734 | } | 2760 | } |
| 2735 | case Tegra::Shader::TextureProcessMode::LZ: { | 2761 | case Tegra::Shader::TextureProcessMode::LZ: { |
| 2736 | if (depth_compare && is_array) { | 2762 | if (depth_compare && is_array) { |
| 2737 | texture = "texture(" + sampler + ", coords)"; | 2763 | // Since we got an OpenGL limitation, we set bias very high to enforce mipmap 0 |
| 2764 | texture = "texture(" + sampler + ", coords, 1000.0)"; | ||
| 2738 | } else { | 2765 | } else { |
| 2739 | texture = "textureLod(" + sampler + ", coords, 0.0)"; | 2766 | texture = "textureLod(" + sampler + ", coords, 0.0)"; |
| 2740 | } | 2767 | } |
| 2741 | break; | 2768 | break; |
| 2742 | } | 2769 | } |
| 2743 | case Tegra::Shader::TextureProcessMode::LL: { | 2770 | case Tegra::Shader::TextureProcessMode::LL: { |
| 2744 | const std::string op_c = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | 2771 | texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; |
| 2745 | texture = "textureLod(" + sampler + ", coords, " + op_c + ')'; | ||
| 2746 | break; | 2772 | break; |
| 2747 | } | 2773 | } |
| 2748 | default: { | 2774 | default: { |