summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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;