summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-03-29 18:37:37 -0300
committerGravatar ReinUsesLisp2019-03-30 02:55:18 -0300
commite8abe4b77c51cded78b3637296547e0d96b2e36a (patch)
tree8e2986a6687b9b5d82f6e161e5648eca8e86d335 /src
parentshader_ir/decode: Implement AOFFI for TEX and TLD4 (diff)
downloadyuzu-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.cpp123
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;
34using ShaderStage = Tegra::Engines::Maxwell3D::Regs::ShaderStage; 34using ShaderStage = Tegra::Engines::Maxwell3D::Regs::ShaderStage;
35using Operation = const OperationNode&; 35using Operation = const OperationNode&;
36 36
37enum class Type { Bool, Bool2, Float, Int, Uint, HalfFloat };
38
39namespace {
40struct TextureAoffi {};
41using TextureArgument = std::pair<Type, Node>;
42using TextureIR = std::variant<TextureAoffi, TextureArgument>;
43} // namespace
44
37enum : u32 { POSITION_VARYING_LOCATION = 0, GENERIC_VARYING_START_LOCATION = 1 }; 45enum : u32 { POSITION_VARYING_LOCATION = 0, GENERIC_VARYING_START_LOCATION = 1 };
38constexpr u32 MAX_CONSTBUFFER_ELEMENTS = 46constexpr u32 MAX_CONSTBUFFER_ELEMENTS =
39 static_cast<u32>(RasterizerOpenGL::MaxConstbufferSize) / (4 * sizeof(float)); 47 static_cast<u32>(RasterizerOpenGL::MaxConstbufferSize) / (4 * sizeof(float));
40constexpr u32 MAX_GLOBALMEMORY_ELEMENTS = 48constexpr u32 MAX_GLOBALMEMORY_ELEMENTS =
41 static_cast<u32>(RasterizerOpenGL::MaxGlobalMemorySize) / sizeof(float); 49 static_cast<u32>(RasterizerOpenGL::MaxGlobalMemorySize) / sizeof(float);
42 50
43enum class Type { Bool, Bool2, Float, Int, Uint, HalfFloat };
44
45class ShaderWriter { 51class ShaderWriter {
46public: 52public:
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 }