diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 148 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 47 |
2 files changed, 192 insertions, 3 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 6e555ea03..88b4d0bac 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -271,6 +271,15 @@ enum class TextureProcessMode : u64 { | |||
| 271 | LLA = 7 // Load LOD. The A is unknown, does not appear to differ with LL | 271 | LLA = 7 // Load LOD. The A is unknown, does not appear to differ with LL |
| 272 | }; | 272 | }; |
| 273 | 273 | ||
| 274 | enum class TextureMiscMode : u64 { | ||
| 275 | DC, | ||
| 276 | AOFFI, // Uses Offset | ||
| 277 | NDV, | ||
| 278 | NODEP, | ||
| 279 | MZ, | ||
| 280 | PTP, | ||
| 281 | }; | ||
| 282 | |||
| 274 | enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; | 283 | enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; |
| 275 | enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; | 284 | enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; |
| 276 | 285 | ||
| @@ -590,42 +599,127 @@ union Instruction { | |||
| 590 | BitField<28, 1, u64> array; | 599 | BitField<28, 1, u64> array; |
| 591 | BitField<29, 2, TextureType> texture_type; | 600 | BitField<29, 2, TextureType> texture_type; |
| 592 | BitField<31, 4, u64> component_mask; | 601 | BitField<31, 4, u64> component_mask; |
| 602 | BitField<49, 1, u64> nodep_flag; | ||
| 603 | BitField<50, 1, u64> dc_flag; | ||
| 604 | BitField<54, 1, u64> aoffi_flag; | ||
| 593 | BitField<55, 3, TextureProcessMode> process_mode; | 605 | BitField<55, 3, TextureProcessMode> process_mode; |
| 594 | 606 | ||
| 595 | bool IsComponentEnabled(std::size_t component) const { | 607 | bool IsComponentEnabled(std::size_t component) const { |
| 596 | return ((1ull << component) & component_mask) != 0; | 608 | return ((1ull << component) & component_mask) != 0; |
| 597 | } | 609 | } |
| 610 | |||
| 611 | TextureProcessMode GetTextureProcessMode() const { | ||
| 612 | return process_mode; | ||
| 613 | } | ||
| 614 | |||
| 615 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 616 | switch (mode) { | ||
| 617 | case TextureMiscMode::DC: | ||
| 618 | return dc_flag != 0; | ||
| 619 | case TextureMiscMode::NODEP: | ||
| 620 | return nodep_flag != 0; | ||
| 621 | case TextureMiscMode::AOFFI: | ||
| 622 | return aoffi_flag != 0; | ||
| 623 | default: | ||
| 624 | break; | ||
| 625 | } | ||
| 626 | return false; | ||
| 627 | } | ||
| 598 | } tex; | 628 | } tex; |
| 599 | 629 | ||
| 600 | union { | 630 | union { |
| 601 | BitField<22, 6, TextureQueryType> query_type; | 631 | BitField<22, 6, TextureQueryType> query_type; |
| 602 | BitField<31, 4, u64> component_mask; | 632 | BitField<31, 4, u64> component_mask; |
| 633 | BitField<49, 1, u64> nodep_flag; | ||
| 634 | |||
| 635 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 636 | switch (mode) { | ||
| 637 | case TextureMiscMode::NODEP: | ||
| 638 | return nodep_flag != 0; | ||
| 639 | default: | ||
| 640 | break; | ||
| 641 | } | ||
| 642 | return false; | ||
| 643 | } | ||
| 603 | } txq; | 644 | } txq; |
| 604 | 645 | ||
| 605 | union { | 646 | union { |
| 606 | BitField<28, 1, u64> array; | 647 | BitField<28, 1, u64> array; |
| 607 | BitField<29, 2, TextureType> texture_type; | 648 | BitField<29, 2, TextureType> texture_type; |
| 608 | BitField<31, 4, u64> component_mask; | 649 | BitField<31, 4, u64> component_mask; |
| 650 | BitField<35, 1, u64> ndv_flag; | ||
| 651 | BitField<49, 1, u64> nodep_flag; | ||
| 609 | 652 | ||
| 610 | bool IsComponentEnabled(std::size_t component) const { | 653 | bool IsComponentEnabled(std::size_t component) const { |
| 611 | return ((1ull << component) & component_mask) != 0; | 654 | return ((1ull << component) & component_mask) != 0; |
| 612 | } | 655 | } |
| 656 | |||
| 657 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 658 | switch (mode) { | ||
| 659 | case TextureMiscMode::NDV: | ||
| 660 | return (ndv_flag != 0); | ||
| 661 | case TextureMiscMode::NODEP: | ||
| 662 | return (nodep_flag != 0); | ||
| 663 | default: | ||
| 664 | break; | ||
| 665 | } | ||
| 666 | return false; | ||
| 667 | } | ||
| 613 | } tmml; | 668 | } tmml; |
| 614 | 669 | ||
| 615 | union { | 670 | union { |
| 616 | BitField<28, 1, u64> array; | 671 | BitField<28, 1, u64> array; |
| 617 | BitField<29, 2, TextureType> texture_type; | 672 | BitField<29, 2, TextureType> texture_type; |
| 673 | BitField<35, 1, u64> ndv_flag; | ||
| 674 | BitField<49, 1, u64> nodep_flag; | ||
| 675 | BitField<50, 1, u64> dc_flag; | ||
| 676 | BitField<54, 2, u64> info; | ||
| 618 | BitField<56, 2, u64> component; | 677 | BitField<56, 2, u64> component; |
| 678 | |||
| 679 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 680 | switch (mode) { | ||
| 681 | case TextureMiscMode::NDV: | ||
| 682 | return ndv_flag != 0; | ||
| 683 | case TextureMiscMode::NODEP: | ||
| 684 | return nodep_flag != 0; | ||
| 685 | case TextureMiscMode::DC: | ||
| 686 | return dc_flag != 0; | ||
| 687 | case TextureMiscMode::AOFFI: | ||
| 688 | return info == 1; | ||
| 689 | case TextureMiscMode::PTP: | ||
| 690 | return info == 2; | ||
| 691 | default: | ||
| 692 | break; | ||
| 693 | } | ||
| 694 | return false; | ||
| 695 | } | ||
| 619 | } tld4; | 696 | } tld4; |
| 620 | 697 | ||
| 621 | union { | 698 | union { |
| 699 | BitField<49, 1, u64> nodep_flag; | ||
| 700 | BitField<50, 1, u64> dc_flag; | ||
| 701 | BitField<51, 1, u64> aoffi_flag; | ||
| 622 | BitField<52, 2, u64> component; | 702 | BitField<52, 2, u64> component; |
| 703 | |||
| 704 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 705 | switch (mode) { | ||
| 706 | case TextureMiscMode::DC: | ||
| 707 | return dc_flag != 0; | ||
| 708 | case TextureMiscMode::NODEP: | ||
| 709 | return nodep_flag != 0; | ||
| 710 | case TextureMiscMode::AOFFI: | ||
| 711 | return aoffi_flag != 0; | ||
| 712 | default: | ||
| 713 | break; | ||
| 714 | } | ||
| 715 | return false; | ||
| 716 | } | ||
| 623 | } tld4s; | 717 | } tld4s; |
| 624 | 718 | ||
| 625 | union { | 719 | union { |
| 626 | BitField<0, 8, Register> gpr0; | 720 | BitField<0, 8, Register> gpr0; |
| 627 | BitField<28, 8, Register> gpr28; | 721 | BitField<28, 8, Register> gpr28; |
| 628 | BitField<49, 1, u64> nodep; | 722 | BitField<49, 1, u64> nodep_flag; |
| 629 | BitField<50, 3, u64> component_mask_selector; | 723 | BitField<50, 3, u64> component_mask_selector; |
| 630 | BitField<53, 4, u64> texture_info; | 724 | BitField<53, 4, u64> texture_info; |
| 631 | 725 | ||
| @@ -645,6 +739,37 @@ union Instruction { | |||
| 645 | UNREACHABLE(); | 739 | UNREACHABLE(); |
| 646 | } | 740 | } |
| 647 | 741 | ||
| 742 | TextureProcessMode GetTextureProcessMode() const { | ||
| 743 | switch (texture_info) { | ||
| 744 | case 0: | ||
| 745 | case 2: | ||
| 746 | case 6: | ||
| 747 | case 8: | ||
| 748 | case 9: | ||
| 749 | case 11: | ||
| 750 | return TextureProcessMode::LZ; | ||
| 751 | case 3: | ||
| 752 | case 5: | ||
| 753 | case 13: | ||
| 754 | return TextureProcessMode::LL; | ||
| 755 | default: | ||
| 756 | break; | ||
| 757 | } | ||
| 758 | return TextureProcessMode::None; | ||
| 759 | } | ||
| 760 | |||
| 761 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 762 | switch (mode) { | ||
| 763 | case TextureMiscMode::DC: | ||
| 764 | return (texture_info >= 4 && texture_info <= 6) || texture_info == 9; | ||
| 765 | case TextureMiscMode::NODEP: | ||
| 766 | return nodep_flag != 0; | ||
| 767 | default: | ||
| 768 | break; | ||
| 769 | } | ||
| 770 | return false; | ||
| 771 | } | ||
| 772 | |||
| 648 | bool IsArrayTexture() const { | 773 | bool IsArrayTexture() const { |
| 649 | // TEXS only supports Texture2D arrays. | 774 | // TEXS only supports Texture2D arrays. |
| 650 | return texture_info >= 7 && texture_info <= 9; | 775 | return texture_info >= 7 && texture_info <= 9; |
| @@ -673,6 +798,7 @@ union Instruction { | |||
| 673 | } texs; | 798 | } texs; |
| 674 | 799 | ||
| 675 | union { | 800 | union { |
| 801 | BitField<49, 1, u64> nodep_flag; | ||
| 676 | BitField<53, 4, u64> texture_info; | 802 | BitField<53, 4, u64> texture_info; |
| 677 | 803 | ||
| 678 | TextureType GetTextureType() const { | 804 | TextureType GetTextureType() const { |
| @@ -693,6 +819,26 @@ union Instruction { | |||
| 693 | UNREACHABLE(); | 819 | UNREACHABLE(); |
| 694 | } | 820 | } |
| 695 | 821 | ||
| 822 | TextureProcessMode GetTextureProcessMode() const { | ||
| 823 | if (texture_info == 1 || texture_info == 5 || texture_info == 12) | ||
| 824 | return TextureProcessMode::LL; | ||
| 825 | return TextureProcessMode::LZ; | ||
| 826 | } | ||
| 827 | |||
| 828 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 829 | switch (mode) { | ||
| 830 | case TextureMiscMode::AOFFI: | ||
| 831 | return texture_info == 12 || texture_info == 4; | ||
| 832 | case TextureMiscMode::MZ: | ||
| 833 | return texture_info == 5; | ||
| 834 | case TextureMiscMode::NODEP: | ||
| 835 | return nodep_flag != 0; | ||
| 836 | default: | ||
| 837 | break; | ||
| 838 | } | ||
| 839 | return false; | ||
| 840 | } | ||
| 841 | |||
| 696 | bool IsArrayTexture() const { | 842 | bool IsArrayTexture() const { |
| 697 | // TEXS only supports Texture2D arrays. | 843 | // TEXS only supports Texture2D arrays. |
| 698 | return texture_info == 8; | 844 | return texture_info == 8; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index a1638c12e..cca6cc6ff 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -938,8 +938,6 @@ private: | |||
| 938 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle | 938 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle |
| 939 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 | 939 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 |
| 940 | 940 | ||
| 941 | ASSERT_MSG(instr.texs.nodep == 0, "TEXS nodep not implemented"); | ||
| 942 | |||
| 943 | std::size_t written_components = 0; | 941 | std::size_t written_components = 0; |
| 944 | for (u32 component = 0; component < 4; ++component) { | 942 | for (u32 component = 0; component < 4; ++component) { |
| 945 | if (!instr.texs.IsComponentEnabled(component)) { | 943 | if (!instr.texs.IsComponentEnabled(component)) { |
| @@ -1853,6 +1851,13 @@ private: | |||
| 1853 | Tegra::Shader::TextureType texture_type{instr.tex.texture_type}; | 1851 | Tegra::Shader::TextureType texture_type{instr.tex.texture_type}; |
| 1854 | std::string coord; | 1852 | std::string coord; |
| 1855 | 1853 | ||
| 1854 | ASSERT_MSG(!instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | ||
| 1855 | "NODEP is not implemented"); | ||
| 1856 | ASSERT_MSG(!instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), | ||
| 1857 | "AOFFI is not implemented"); | ||
| 1858 | ASSERT_MSG(!instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC), | ||
| 1859 | "DC is not implemented"); | ||
| 1860 | |||
| 1856 | switch (texture_type) { | 1861 | switch (texture_type) { |
| 1857 | case Tegra::Shader::TextureType::Texture1D: { | 1862 | case Tegra::Shader::TextureType::Texture1D: { |
| 1858 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 1863 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| @@ -1935,6 +1940,11 @@ private: | |||
| 1935 | Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()}; | 1940 | Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()}; |
| 1936 | bool is_array{instr.texs.IsArrayTexture()}; | 1941 | bool is_array{instr.texs.IsArrayTexture()}; |
| 1937 | 1942 | ||
| 1943 | ASSERT_MSG(!instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | ||
| 1944 | "NODEP is not implemented"); | ||
| 1945 | ASSERT_MSG(!instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC), | ||
| 1946 | "DC is not implemented"); | ||
| 1947 | |||
| 1938 | switch (texture_type) { | 1948 | switch (texture_type) { |
| 1939 | case Tegra::Shader::TextureType::Texture2D: { | 1949 | case Tegra::Shader::TextureType::Texture2D: { |
| 1940 | if (is_array) { | 1950 | if (is_array) { |
| @@ -1971,6 +1981,13 @@ private: | |||
| 1971 | ASSERT(instr.tlds.IsArrayTexture() == false); | 1981 | ASSERT(instr.tlds.IsArrayTexture() == false); |
| 1972 | std::string coord; | 1982 | std::string coord; |
| 1973 | 1983 | ||
| 1984 | ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | ||
| 1985 | "NODEP is not implemented"); | ||
| 1986 | ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), | ||
| 1987 | "AOFFI is not implemented"); | ||
| 1988 | ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::MZ), | ||
| 1989 | "MZ is not implemented"); | ||
| 1990 | |||
| 1974 | switch (instr.tlds.GetTextureType()) { | 1991 | switch (instr.tlds.GetTextureType()) { |
| 1975 | case Tegra::Shader::TextureType::Texture2D: { | 1992 | case Tegra::Shader::TextureType::Texture2D: { |
| 1976 | if (instr.tlds.IsArrayTexture()) { | 1993 | if (instr.tlds.IsArrayTexture()) { |
| @@ -1999,6 +2016,17 @@ private: | |||
| 1999 | ASSERT(instr.tld4.array == 0); | 2016 | ASSERT(instr.tld4.array == 0); |
| 2000 | std::string coord; | 2017 | std::string coord; |
| 2001 | 2018 | ||
| 2019 | ASSERT_MSG(!instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | ||
| 2020 | "NODEP is not implemented"); | ||
| 2021 | ASSERT_MSG(!instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), | ||
| 2022 | "AOFFI is not implemented"); | ||
| 2023 | ASSERT_MSG(!instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC), | ||
| 2024 | "DC is not implemented"); | ||
| 2025 | ASSERT_MSG(!instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NDV), | ||
| 2026 | "NDV is not implemented"); | ||
| 2027 | ASSERT_MSG(!instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::PTP), | ||
| 2028 | "PTP is not implemented"); | ||
| 2029 | |||
| 2002 | switch (instr.tld4.texture_type) { | 2030 | switch (instr.tld4.texture_type) { |
| 2003 | case Tegra::Shader::TextureType::Texture2D: { | 2031 | case Tegra::Shader::TextureType::Texture2D: { |
| 2004 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2032 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| @@ -2036,6 +2064,13 @@ private: | |||
| 2036 | break; | 2064 | break; |
| 2037 | } | 2065 | } |
| 2038 | case OpCode::Id::TLD4S: { | 2066 | case OpCode::Id::TLD4S: { |
| 2067 | ASSERT_MSG(!instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | ||
| 2068 | "NODEP is not implemented"); | ||
| 2069 | ASSERT_MSG(!instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), | ||
| 2070 | "AOFFI is not implemented"); | ||
| 2071 | ASSERT_MSG(!instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC), | ||
| 2072 | "DC is not implemented"); | ||
| 2073 | |||
| 2039 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | 2074 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |
| 2040 | const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20); | 2075 | const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20); |
| 2041 | // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. | 2076 | // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. |
| @@ -2048,6 +2083,9 @@ private: | |||
| 2048 | break; | 2083 | break; |
| 2049 | } | 2084 | } |
| 2050 | case OpCode::Id::TXQ: { | 2085 | case OpCode::Id::TXQ: { |
| 2086 | ASSERT_MSG(!instr.txq.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | ||
| 2087 | "NODEP is not implemented"); | ||
| 2088 | |||
| 2051 | // TODO: the new commits on the texture refactor, change the way samplers work. | 2089 | // TODO: the new commits on the texture refactor, change the way samplers work. |
| 2052 | // Sadly, not all texture instructions specify the type of texture their sampler | 2090 | // Sadly, not all texture instructions specify the type of texture their sampler |
| 2053 | // uses. This must be fixed at a later instance. | 2091 | // uses. This must be fixed at a later instance. |
| @@ -2068,6 +2106,11 @@ private: | |||
| 2068 | break; | 2106 | break; |
| 2069 | } | 2107 | } |
| 2070 | case OpCode::Id::TMML: { | 2108 | case OpCode::Id::TMML: { |
| 2109 | ASSERT_MSG(!instr.tmml.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | ||
| 2110 | "NODEP is not implemented"); | ||
| 2111 | ASSERT_MSG(!instr.tmml.UsesMiscMode(Tegra::Shader::TextureMiscMode::NDV), | ||
| 2112 | "NDV is not implemented"); | ||
| 2113 | |||
| 2071 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | 2114 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |
| 2072 | const std::string op_b = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2115 | const std::string op_b = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2073 | const bool is_array = instr.tmml.array != 0; | 2116 | const bool is_array = instr.tmml.array != 0; |