summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-12-30 13:54:53 -0400
committerGravatar FernandoS272019-12-30 15:31:48 -0400
commitb3371ed09e6866e235141119f9eecc2bb962dc8d (patch)
tree06619df9bd72cc0d73a3869b040b20804e2d3109 /src
parentMerge pull request #3250 from ReinUsesLisp/empty-fragment (diff)
downloadyuzu-b3371ed09e6866e235141119f9eecc2bb962dc8d.tar.gz
yuzu-b3371ed09e6866e235141119f9eecc2bb962dc8d.tar.xz
yuzu-b3371ed09e6866e235141119f9eecc2bb962dc8d.zip
Shader_IR: add the ability to amend code in the shader ir.
This commit introduces a mechanism by which shader IR code can be amended and extended. This useful for track algorithms where certain information can derived from before the track such as indexes to array samplers.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp15
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp18
-rw-r--r--src/video_core/shader/node.h28
-rw-r--r--src/video_core/shader/shader_ir.cpp6
-rw-r--r--src/video_core/shader/shader_ir.h8
5 files changed, 72 insertions, 3 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index a311dbcfe..e1730821f 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -751,6 +751,11 @@ private:
751 751
752 Expression Visit(const Node& node) { 752 Expression Visit(const Node& node) {
753 if (const auto operation = std::get_if<OperationNode>(&*node)) { 753 if (const auto operation = std::get_if<OperationNode>(&*node)) {
754 auto amend_index = operation->GetAmendIndex();
755 if (amend_index) {
756 const Node& amend_node = ir.GetAmendNode(*amend_index);
757 Visit(amend_node).CheckVoid();
758 }
754 const auto operation_index = static_cast<std::size_t>(operation->GetCode()); 759 const auto operation_index = static_cast<std::size_t>(operation->GetCode());
755 if (operation_index >= operation_decompilers.size()) { 760 if (operation_index >= operation_decompilers.size()) {
756 UNREACHABLE_MSG("Out of bounds operation: {}", operation_index); 761 UNREACHABLE_MSG("Out of bounds operation: {}", operation_index);
@@ -872,6 +877,11 @@ private:
872 } 877 }
873 878
874 if (const auto conditional = std::get_if<ConditionalNode>(&*node)) { 879 if (const auto conditional = std::get_if<ConditionalNode>(&*node)) {
880 auto amend_index = conditional->GetAmendIndex();
881 if (amend_index) {
882 const Node& amend_node = ir.GetAmendNode(*amend_index);
883 Visit(amend_node).CheckVoid();
884 }
875 // It's invalid to call conditional on nested nodes, use an operation instead 885 // It's invalid to call conditional on nested nodes, use an operation instead
876 code.AddLine("if ({}) {{", Visit(conditional->GetCondition()).AsBool()); 886 code.AddLine("if ({}) {{", Visit(conditional->GetCondition()).AsBool());
877 ++code.scope; 887 ++code.scope;
@@ -884,6 +894,11 @@ private:
884 } 894 }
885 895
886 if (const auto comment = std::get_if<CommentNode>(&*node)) { 896 if (const auto comment = std::get_if<CommentNode>(&*node)) {
897 auto amend_index = comment->GetAmendIndex();
898 if (amend_index) {
899 const Node& amend_node = ir.GetAmendNode(*amend_index);
900 Visit(amend_node).CheckVoid();
901 }
887 code.AddLine("// " + comment->GetText()); 902 code.AddLine("// " + comment->GetText());
888 return {}; 903 return {};
889 } 904 }
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index a8baf91de..50feeb003 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -954,6 +954,12 @@ private:
954 954
955 Expression Visit(const Node& node) { 955 Expression Visit(const Node& node) {
956 if (const auto operation = std::get_if<OperationNode>(&*node)) { 956 if (const auto operation = std::get_if<OperationNode>(&*node)) {
957 auto amend_index = operation->GetAmendIndex();
958 if (amend_index) {
959 const Node& amend_node = ir.GetAmendNode(*amend_index);
960 [[maybe_unused]] const Type type = Visit(amend_node).type;
961 ASSERT(type == Type::Void);
962 }
957 const auto operation_index = static_cast<std::size_t>(operation->GetCode()); 963 const auto operation_index = static_cast<std::size_t>(operation->GetCode());
958 const auto decompiler = operation_decompilers[operation_index]; 964 const auto decompiler = operation_decompilers[operation_index];
959 if (decompiler == nullptr) { 965 if (decompiler == nullptr) {
@@ -1142,6 +1148,12 @@ private:
1142 } 1148 }
1143 1149
1144 if (const auto conditional = std::get_if<ConditionalNode>(&*node)) { 1150 if (const auto conditional = std::get_if<ConditionalNode>(&*node)) {
1151 auto amend_index = conditional->GetAmendIndex();
1152 if (amend_index) {
1153 const Node& amend_node = ir.GetAmendNode(*amend_index);
1154 [[maybe_unused]] const Type type = Visit(amend_node).type;
1155 ASSERT(type == Type::Void);
1156 }
1145 // It's invalid to call conditional on nested nodes, use an operation instead 1157 // It's invalid to call conditional on nested nodes, use an operation instead
1146 const Id true_label = OpLabel(); 1158 const Id true_label = OpLabel();
1147 const Id skip_label = OpLabel(); 1159 const Id skip_label = OpLabel();
@@ -1164,6 +1176,12 @@ private:
1164 } 1176 }
1165 1177
1166 if (const auto comment = std::get_if<CommentNode>(&*node)) { 1178 if (const auto comment = std::get_if<CommentNode>(&*node)) {
1179 auto amend_index = comment->GetAmendIndex();
1180 if (amend_index) {
1181 const Node& amend_node = ir.GetAmendNode(*amend_index);
1182 [[maybe_unused]] const Type type = Visit(amend_node).type;
1183 ASSERT(type == Type::Void);
1184 }
1167 Name(OpUndef(t_void), comment->GetText()); 1185 Name(OpUndef(t_void), comment->GetText());
1168 return {}; 1186 return {};
1169 } 1187 }
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index 4d2f4d6a8..42e82ab74 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -392,8 +392,30 @@ struct MetaImage {
392using Meta = 392using Meta =
393 std::variant<MetaArithmetic, MetaTexture, MetaImage, MetaStackClass, Tegra::Shader::HalfType>; 393 std::variant<MetaArithmetic, MetaTexture, MetaImage, MetaStackClass, Tegra::Shader::HalfType>;
394 394
395class AmendNode {
396public:
397 std::optional<u32> GetAmendIndex() const {
398 if (amend_index == amend_null_index) {
399 return std::nullopt;
400 }
401 return {amend_index};
402 }
403
404 void SetAmendIndex(u32 index) {
405 amend_index = index;
406 }
407
408 void ClearAmend() {
409 amend_index = amend_null_index;
410 }
411
412private:
413 static constexpr u32 amend_null_index = 0xFFFFFFFF;
414 u32 amend_index{amend_null_index};
415};
416
395/// Holds any kind of operation that can be done in the IR 417/// Holds any kind of operation that can be done in the IR
396class OperationNode final { 418class OperationNode final : public AmendNode {
397public: 419public:
398 explicit OperationNode(OperationCode code) : OperationNode(code, Meta{}) {} 420 explicit OperationNode(OperationCode code) : OperationNode(code, Meta{}) {}
399 421
@@ -433,7 +455,7 @@ private:
433}; 455};
434 456
435/// Encloses inside any kind of node that returns a boolean conditionally-executed code 457/// Encloses inside any kind of node that returns a boolean conditionally-executed code
436class ConditionalNode final { 458class ConditionalNode final : public AmendNode {
437public: 459public:
438 explicit ConditionalNode(Node condition, std::vector<Node>&& code) 460 explicit ConditionalNode(Node condition, std::vector<Node>&& code)
439 : condition{std::move(condition)}, code{std::move(code)} {} 461 : condition{std::move(condition)}, code{std::move(code)} {}
@@ -630,7 +652,7 @@ private:
630}; 652};
631 653
632/// Commentary, can be dropped 654/// Commentary, can be dropped
633class CommentNode final { 655class CommentNode final : public AmendNode {
634public: 656public:
635 explicit CommentNode(std::string text) : text{std::move(text)} {} 657 explicit CommentNode(std::string text) : text{std::move(text)} {}
636 658
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 1d9825c76..49678767c 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -446,4 +446,10 @@ Node ShaderIR::BitfieldInsert(Node base, Node insert, u32 offset, u32 bits) {
446 Immediate(bits)); 446 Immediate(bits));
447} 447}
448 448
449u32 ShaderIR::DeclareAmend(Node new_amend) {
450 const u32 id = static_cast<u32>(amend_code.size());
451 amend_code.push_back(new_amend);
452 return id;
453}
454
449} // namespace VideoCommon::Shader 455} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index baed06ccd..52f130e1b 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -176,6 +176,10 @@ public:
176 /// Returns a condition code evaluated from internal flags 176 /// Returns a condition code evaluated from internal flags
177 Node GetConditionCode(Tegra::Shader::ConditionCode cc) const; 177 Node GetConditionCode(Tegra::Shader::ConditionCode cc) const;
178 178
179 const Node& GetAmendNode(u32 index) const {
180 return amend_code[index];
181 }
182
179private: 183private:
180 friend class ASTDecoder; 184 friend class ASTDecoder;
181 185
@@ -392,6 +396,9 @@ private:
392 Tegra::Shader::Instruction instr, 396 Tegra::Shader::Instruction instr,
393 bool is_write); 397 bool is_write);
394 398
399 /// Amends
400 u32 DeclareAmend(Node new_amend);
401
395 const ProgramCode& program_code; 402 const ProgramCode& program_code;
396 const u32 main_offset; 403 const u32 main_offset;
397 const CompilerSettings settings; 404 const CompilerSettings settings;
@@ -406,6 +413,7 @@ private:
406 std::map<u32, NodeBlock> basic_blocks; 413 std::map<u32, NodeBlock> basic_blocks;
407 NodeBlock global_code; 414 NodeBlock global_code;
408 ASTManager program_manager{true, true}; 415 ASTManager program_manager{true, true};
416 NodeBlock amend_code;
409 417
410 std::set<u32> used_registers; 418 std::set<u32> used_registers;
411 std::set<Tegra::Shader::Pred> used_predicates; 419 std::set<Tegra::Shader::Pred> used_predicates;