diff options
| author | 2019-03-29 18:37:37 -0300 | |
|---|---|---|
| committer | 2019-03-30 02:55:18 -0300 | |
| commit | e8abe4b77c51cded78b3637296547e0d96b2e36a (patch) | |
| tree | 8e2986a6687b9b5d82f6e161e5648eca8e86d335 /src | |
| parent | shader_ir/decode: Implement AOFFI for TEX and TLD4 (diff) | |
| download | yuzu-e8abe4b77c51cded78b3637296547e0d96b2e36a.tar.gz yuzu-e8abe4b77c51cded78b3637296547e0d96b2e36a.tar.xz yuzu-e8abe4b77c51cded78b3637296547e0d96b2e36a.zip | |
gl_shader_decompiler: Add AOFFI backing implementation
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 123 |
1 files changed, 85 insertions, 38 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 11d1169f0..df00ea85d 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -34,14 +34,20 @@ using Maxwell = Tegra::Engines::Maxwell3D::Regs; | |||
| 34 | using ShaderStage = Tegra::Engines::Maxwell3D::Regs::ShaderStage; | 34 | using ShaderStage = Tegra::Engines::Maxwell3D::Regs::ShaderStage; |
| 35 | using Operation = const OperationNode&; | 35 | using Operation = const OperationNode&; |
| 36 | 36 | ||
| 37 | enum class Type { Bool, Bool2, Float, Int, Uint, HalfFloat }; | ||
| 38 | |||
| 39 | namespace { | ||
| 40 | struct TextureAoffi {}; | ||
| 41 | using TextureArgument = std::pair<Type, Node>; | ||
| 42 | using TextureIR = std::variant<TextureAoffi, TextureArgument>; | ||
| 43 | } // namespace | ||
| 44 | |||
| 37 | enum : u32 { POSITION_VARYING_LOCATION = 0, GENERIC_VARYING_START_LOCATION = 1 }; | 45 | enum : u32 { POSITION_VARYING_LOCATION = 0, GENERIC_VARYING_START_LOCATION = 1 }; |
| 38 | constexpr u32 MAX_CONSTBUFFER_ELEMENTS = | 46 | constexpr u32 MAX_CONSTBUFFER_ELEMENTS = |
| 39 | static_cast<u32>(RasterizerOpenGL::MaxConstbufferSize) / (4 * sizeof(float)); | 47 | static_cast<u32>(RasterizerOpenGL::MaxConstbufferSize) / (4 * sizeof(float)); |
| 40 | constexpr u32 MAX_GLOBALMEMORY_ELEMENTS = | 48 | constexpr u32 MAX_GLOBALMEMORY_ELEMENTS = |
| 41 | static_cast<u32>(RasterizerOpenGL::MaxGlobalMemorySize) / sizeof(float); | 49 | static_cast<u32>(RasterizerOpenGL::MaxGlobalMemorySize) / sizeof(float); |
| 42 | 50 | ||
| 43 | enum class Type { Bool, Bool2, Float, Int, Uint, HalfFloat }; | ||
| 44 | |||
| 45 | class ShaderWriter { | 51 | class ShaderWriter { |
| 46 | public: | 52 | public: |
| 47 | void AddExpression(std::string_view text) { | 53 | void AddExpression(std::string_view text) { |
| @@ -718,8 +724,8 @@ private: | |||
| 718 | result_type)); | 724 | result_type)); |
| 719 | } | 725 | } |
| 720 | 726 | ||
| 721 | std::string GenerateTexture(Operation operation, const std::string& func, | 727 | std::string GenerateTexture(Operation operation, const std::string& function_suffix, |
| 722 | const std::vector<std::pair<Type, Node>>& extras) { | 728 | const std::vector<TextureIR>& extras) { |
| 723 | constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"}; | 729 | constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"}; |
| 724 | 730 | ||
| 725 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | 731 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| @@ -729,11 +735,11 @@ private: | |||
| 729 | const bool has_array = meta->sampler.IsArray(); | 735 | const bool has_array = meta->sampler.IsArray(); |
| 730 | const bool has_shadow = meta->sampler.IsShadow(); | 736 | const bool has_shadow = meta->sampler.IsShadow(); |
| 731 | 737 | ||
| 732 | std::string expr = func; | 738 | std::string expr = "texture" + function_suffix; |
| 733 | expr += '('; | 739 | if (!meta->aoffi.empty()) { |
| 734 | expr += GetSampler(meta->sampler); | 740 | expr += "Offset"; |
| 735 | expr += ", "; | 741 | } |
| 736 | 742 | expr += '(' + GetSampler(meta->sampler) + ", "; | |
| 737 | expr += coord_constructors.at(count + (has_array ? 1 : 0) + (has_shadow ? 1 : 0) - 1); | 743 | expr += coord_constructors.at(count + (has_array ? 1 : 0) + (has_shadow ? 1 : 0) - 1); |
| 738 | expr += '('; | 744 | expr += '('; |
| 739 | for (std::size_t i = 0; i < count; ++i) { | 745 | for (std::size_t i = 0; i < count; ++i) { |
| @@ -751,36 +757,74 @@ private: | |||
| 751 | } | 757 | } |
| 752 | expr += ')'; | 758 | expr += ')'; |
| 753 | 759 | ||
| 754 | for (const auto& extra_pair : extras) { | 760 | for (const auto& variant : extras) { |
| 755 | const auto [type, operand] = extra_pair; | 761 | if (const auto argument = std::get_if<TextureArgument>(&variant)) { |
| 756 | if (operand == nullptr) { | 762 | expr += GenerateTextureArgument(*argument); |
| 757 | continue; | 763 | } else if (std::get_if<TextureAoffi>(&variant)) { |
| 764 | expr += GenerateTextureAoffi(meta->aoffi); | ||
| 765 | } else { | ||
| 766 | UNREACHABLE(); | ||
| 758 | } | 767 | } |
| 759 | expr += ", "; | 768 | } |
| 760 | 769 | ||
| 761 | switch (type) { | 770 | return expr + ')'; |
| 762 | case Type::Int: | 771 | } |
| 763 | if (const auto immediate = std::get_if<ImmediateNode>(operand)) { | 772 | |
| 764 | // Inline the string as an immediate integer in GLSL (some extra arguments are | 773 | std::string GenerateTextureArgument(TextureArgument argument) { |
| 765 | // required to be constant) | 774 | const auto [type, operand] = argument; |
| 766 | expr += std::to_string(static_cast<s32>(immediate->GetValue())); | 775 | if (operand == nullptr) { |
| 767 | } else { | 776 | return {}; |
| 768 | expr += "ftoi(" + Visit(operand) + ')'; | 777 | } |
| 769 | } | 778 | |
| 770 | break; | 779 | std::string expr = ", "; |
| 771 | case Type::Float: | 780 | switch (type) { |
| 772 | expr += Visit(operand); | 781 | case Type::Int: |
| 773 | break; | 782 | if (const auto immediate = std::get_if<ImmediateNode>(operand)) { |
| 774 | default: { | 783 | // Inline the string as an immediate integer in GLSL (some extra arguments are |
| 775 | const auto type_int = static_cast<u32>(type); | 784 | // required to be constant) |
| 776 | UNIMPLEMENTED_MSG("Unimplemented extra type={}", type_int); | 785 | expr += std::to_string(static_cast<s32>(immediate->GetValue())); |
| 777 | expr += '0'; | 786 | } else { |
| 778 | break; | 787 | expr += "ftoi(" + Visit(operand) + ')'; |
| 779 | } | 788 | } |
| 789 | break; | ||
| 790 | case Type::Float: | ||
| 791 | expr += Visit(operand); | ||
| 792 | break; | ||
| 793 | default: { | ||
| 794 | const auto type_int = static_cast<u32>(type); | ||
| 795 | UNIMPLEMENTED_MSG("Unimplemented extra type={}", type_int); | ||
| 796 | expr += '0'; | ||
| 797 | break; | ||
| 798 | } | ||
| 799 | } | ||
| 800 | return expr; | ||
| 801 | } | ||
| 802 | |||
| 803 | std::string GenerateTextureAoffi(const std::vector<Node>& aoffi) { | ||
| 804 | if (aoffi.empty()) { | ||
| 805 | return {}; | ||
| 806 | } | ||
| 807 | constexpr std::array<const char*, 3> coord_constructors = {"int", "ivec2", "ivec3"}; | ||
| 808 | std::string expr = ", "; | ||
| 809 | expr += coord_constructors.at(aoffi.size() - 1); | ||
| 810 | expr += '('; | ||
| 811 | |||
| 812 | for (std::size_t index = 0; index < aoffi.size(); ++index) { | ||
| 813 | const auto operand{aoffi.at(index)}; | ||
| 814 | if (const auto immediate = std::get_if<ImmediateNode>(operand)) { | ||
| 815 | // Inline the string as an immediate integer in GLSL (AOFFI arguments are required | ||
| 816 | // to be constant by the standard). | ||
| 817 | expr += std::to_string(static_cast<s32>(immediate->GetValue())); | ||
| 818 | } else { | ||
| 819 | expr += "ftoi(" + Visit(operand) + ')'; | ||
| 820 | } | ||
| 821 | if (index + 1 < aoffi.size()) { | ||
| 822 | expr += ", "; | ||
| 780 | } | 823 | } |
| 781 | } | 824 | } |
| 825 | expr += ')'; | ||
| 782 | 826 | ||
| 783 | return expr + ')'; | 827 | return expr; |
| 784 | } | 828 | } |
| 785 | 829 | ||
| 786 | std::string Assign(Operation operation) { | 830 | std::string Assign(Operation operation) { |
| @@ -1159,7 +1203,8 @@ private: | |||
| 1159 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | 1203 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| 1160 | ASSERT(meta); | 1204 | ASSERT(meta); |
| 1161 | 1205 | ||
| 1162 | std::string expr = GenerateTexture(operation, "texture", {{Type::Float, meta->bias}}); | 1206 | std::string expr = GenerateTexture( |
| 1207 | operation, "", {TextureAoffi{}, TextureArgument{Type::Float, meta->bias}}); | ||
| 1163 | if (meta->sampler.IsShadow()) { | 1208 | if (meta->sampler.IsShadow()) { |
| 1164 | expr = "vec4(" + expr + ')'; | 1209 | expr = "vec4(" + expr + ')'; |
| 1165 | } | 1210 | } |
| @@ -1170,7 +1215,8 @@ private: | |||
| 1170 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | 1215 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| 1171 | ASSERT(meta); | 1216 | ASSERT(meta); |
| 1172 | 1217 | ||
| 1173 | std::string expr = GenerateTexture(operation, "textureLod", {{Type::Float, meta->lod}}); | 1218 | std::string expr = GenerateTexture( |
| 1219 | operation, "Lod", {TextureArgument{Type::Float, meta->lod}, TextureAoffi{}}); | ||
| 1174 | if (meta->sampler.IsShadow()) { | 1220 | if (meta->sampler.IsShadow()) { |
| 1175 | expr = "vec4(" + expr + ')'; | 1221 | expr = "vec4(" + expr + ')'; |
| 1176 | } | 1222 | } |
| @@ -1182,7 +1228,8 @@ private: | |||
| 1182 | ASSERT(meta); | 1228 | ASSERT(meta); |
| 1183 | 1229 | ||
| 1184 | const auto type = meta->sampler.IsShadow() ? Type::Float : Type::Int; | 1230 | const auto type = meta->sampler.IsShadow() ? Type::Float : Type::Int; |
| 1185 | return GenerateTexture(operation, "textureGather", {{type, meta->component}}) + | 1231 | return GenerateTexture(operation, "Gather", |
| 1232 | {TextureArgument{type, meta->component}, TextureAoffi{}}) + | ||
| 1186 | GetSwizzle(meta->element); | 1233 | GetSwizzle(meta->element); |
| 1187 | } | 1234 | } |
| 1188 | 1235 | ||
| @@ -1211,8 +1258,8 @@ private: | |||
| 1211 | ASSERT(meta); | 1258 | ASSERT(meta); |
| 1212 | 1259 | ||
| 1213 | if (meta->element < 2) { | 1260 | if (meta->element < 2) { |
| 1214 | return "itof(int((" + GenerateTexture(operation, "textureQueryLod", {}) + | 1261 | return "itof(int((" + GenerateTexture(operation, "QueryLod", {}) + " * vec2(256))" + |
| 1215 | " * vec2(256))" + GetSwizzle(meta->element) + "))"; | 1262 | GetSwizzle(meta->element) + "))"; |
| 1216 | } | 1263 | } |
| 1217 | return "0"; | 1264 | return "0"; |
| 1218 | } | 1265 | } |