diff options
| author | 2020-01-07 14:53:46 -0400 | |
|---|---|---|
| committer | 2020-01-24 16:43:31 -0400 | |
| commit | 3c34678627eeb1b48375cf70ec38b72691fedd1e (patch) | |
| tree | 4a1ceb51da3946c9551e62f2bea6163db361ae48 /src | |
| parent | GL Backend: Introduce indexed samplers into the GL backend (diff) | |
| download | yuzu-3c34678627eeb1b48375cf70ec38b72691fedd1e.tar.gz yuzu-3c34678627eeb1b48375cf70ec38b72691fedd1e.tar.xz yuzu-3c34678627eeb1b48375cf70ec38b72691fedd1e.zip | |
Shader_IR: Implement Injectable Custom Variables to the IR.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 17 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 9 |
5 files changed, 70 insertions, 1 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 4b35396f9..8b413ae9a 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -391,6 +391,7 @@ public: | |||
| 391 | DeclareVertex(); | 391 | DeclareVertex(); |
| 392 | DeclareGeometry(); | 392 | DeclareGeometry(); |
| 393 | DeclareRegisters(); | 393 | DeclareRegisters(); |
| 394 | DeclareCustomVariables(); | ||
| 394 | DeclarePredicates(); | 395 | DeclarePredicates(); |
| 395 | DeclareLocalMemory(); | 396 | DeclareLocalMemory(); |
| 396 | DeclareInternalFlags(); | 397 | DeclareInternalFlags(); |
| @@ -503,6 +504,16 @@ private: | |||
| 503 | } | 504 | } |
| 504 | } | 505 | } |
| 505 | 506 | ||
| 507 | void DeclareCustomVariables() { | ||
| 508 | const u32 cv_num = ir.GetCustomVariablesAmount(); | ||
| 509 | for (u32 i = 0; i < cv_num; ++i) { | ||
| 510 | code.AddLine("float {} = 0.0f;", GetCustomVariable(i)); | ||
| 511 | } | ||
| 512 | if (cv_num > 0) { | ||
| 513 | code.AddNewLine(); | ||
| 514 | } | ||
| 515 | } | ||
| 516 | |||
| 506 | void DeclarePredicates() { | 517 | void DeclarePredicates() { |
| 507 | const auto& predicates = ir.GetPredicates(); | 518 | const auto& predicates = ir.GetPredicates(); |
| 508 | for (const auto pred : predicates) { | 519 | for (const auto pred : predicates) { |
| @@ -780,6 +791,11 @@ private: | |||
| 780 | return {GetRegister(index), Type::Float}; | 791 | return {GetRegister(index), Type::Float}; |
| 781 | } | 792 | } |
| 782 | 793 | ||
| 794 | if (const auto cv = std::get_if<CustomVarNode>(&*node)) { | ||
| 795 | const u32 index = cv->GetIndex(); | ||
| 796 | return {GetCustomVariable(index), Type::Float}; | ||
| 797 | } | ||
| 798 | |||
| 783 | if (const auto immediate = std::get_if<ImmediateNode>(&*node)) { | 799 | if (const auto immediate = std::get_if<ImmediateNode>(&*node)) { |
| 784 | const u32 value = immediate->GetValue(); | 800 | const u32 value = immediate->GetValue(); |
| 785 | if (value < 10) { | 801 | if (value < 10) { |
| @@ -2250,6 +2266,10 @@ private: | |||
| 2250 | return GetDeclarationWithSuffix(index, "gpr"); | 2266 | return GetDeclarationWithSuffix(index, "gpr"); |
| 2251 | } | 2267 | } |
| 2252 | 2268 | ||
| 2269 | std::string GetCustomVariable(u32 index) const { | ||
| 2270 | return GetDeclarationWithSuffix(index, "custom_var"); | ||
| 2271 | } | ||
| 2272 | |||
| 2253 | std::string GetPredicate(Tegra::Shader::Pred pred) const { | 2273 | std::string GetPredicate(Tegra::Shader::Pred pred) const { |
| 2254 | return GetDeclarationWithSuffix(static_cast<u32>(pred), "pred"); | 2274 | return GetDeclarationWithSuffix(static_cast<u32>(pred), "pred"); |
| 2255 | } | 2275 | } |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index dd6d2ef03..bf797dad3 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -353,6 +353,7 @@ private: | |||
| 353 | DeclareFragment(); | 353 | DeclareFragment(); |
| 354 | DeclareCompute(); | 354 | DeclareCompute(); |
| 355 | DeclareRegisters(); | 355 | DeclareRegisters(); |
| 356 | DeclareCustomVariables(); | ||
| 356 | DeclarePredicates(); | 357 | DeclarePredicates(); |
| 357 | DeclareLocalMemory(); | 358 | DeclareLocalMemory(); |
| 358 | DeclareSharedMemory(); | 359 | DeclareSharedMemory(); |
| @@ -587,6 +588,15 @@ private: | |||
| 587 | } | 588 | } |
| 588 | } | 589 | } |
| 589 | 590 | ||
| 591 | void DeclareCustomVariables() { | ||
| 592 | const u32 cv_num = ir.GetCustomVariablesAmount(); | ||
| 593 | for (u32 i = 0; i < cv_num; ++i) { | ||
| 594 | const Id id = OpVariable(t_prv_float, spv::StorageClass::Private, v_float_zero); | ||
| 595 | Name(id, fmt::format("custom_var_{}", i)); | ||
| 596 | custom_variables.emplace(i, AddGlobalVariable(id)); | ||
| 597 | } | ||
| 598 | } | ||
| 599 | |||
| 590 | void DeclarePredicates() { | 600 | void DeclarePredicates() { |
| 591 | for (const auto pred : ir.GetPredicates()) { | 601 | for (const auto pred : ir.GetPredicates()) { |
| 592 | const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false); | 602 | const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false); |
| @@ -974,6 +984,11 @@ private: | |||
| 974 | return {OpLoad(t_float, registers.at(index)), Type::Float}; | 984 | return {OpLoad(t_float, registers.at(index)), Type::Float}; |
| 975 | } | 985 | } |
| 976 | 986 | ||
| 987 | if (const auto cv = std::get_if<CustomVarNode>(&*node)) { | ||
| 988 | const u32 index = cv->GetIndex(); | ||
| 989 | return {OpLoad(t_float, custom_variables.at(index)), Type::Float}; | ||
| 990 | } | ||
| 991 | |||
| 977 | if (const auto immediate = std::get_if<ImmediateNode>(&*node)) { | 992 | if (const auto immediate = std::get_if<ImmediateNode>(&*node)) { |
| 978 | return {Constant(t_uint, immediate->GetValue()), Type::Uint}; | 993 | return {Constant(t_uint, immediate->GetValue()), Type::Uint}; |
| 979 | } | 994 | } |
| @@ -2505,6 +2520,7 @@ private: | |||
| 2505 | Id out_vertex{}; | 2520 | Id out_vertex{}; |
| 2506 | Id in_vertex{}; | 2521 | Id in_vertex{}; |
| 2507 | std::map<u32, Id> registers; | 2522 | std::map<u32, Id> registers; |
| 2523 | std::map<u32, Id> custom_variables; | ||
| 2508 | std::map<Tegra::Shader::Pred, Id> predicates; | 2524 | std::map<Tegra::Shader::Pred, Id> predicates; |
| 2509 | std::map<u32, Id> flow_variables; | 2525 | std::map<u32, Id> flow_variables; |
| 2510 | Id local_memory{}; | 2526 | Id local_memory{}; |
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 2f29b9506..db06767f6 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h | |||
| @@ -212,6 +212,7 @@ enum class MetaStackClass { | |||
| 212 | class OperationNode; | 212 | class OperationNode; |
| 213 | class ConditionalNode; | 213 | class ConditionalNode; |
| 214 | class GprNode; | 214 | class GprNode; |
| 215 | class CustomVarNode; | ||
| 215 | class ImmediateNode; | 216 | class ImmediateNode; |
| 216 | class InternalFlagNode; | 217 | class InternalFlagNode; |
| 217 | class PredicateNode; | 218 | class PredicateNode; |
| @@ -223,7 +224,7 @@ class SmemNode; | |||
| 223 | class GmemNode; | 224 | class GmemNode; |
| 224 | class CommentNode; | 225 | class CommentNode; |
| 225 | 226 | ||
| 226 | using NodeData = std::variant<OperationNode, ConditionalNode, GprNode, ImmediateNode, | 227 | using NodeData = std::variant<OperationNode, ConditionalNode, GprNode, CustomVarNode, ImmediateNode, |
| 227 | InternalFlagNode, PredicateNode, AbufNode, PatchNode, CbufNode, | 228 | InternalFlagNode, PredicateNode, AbufNode, PatchNode, CbufNode, |
| 228 | LmemNode, SmemNode, GmemNode, CommentNode>; | 229 | LmemNode, SmemNode, GmemNode, CommentNode>; |
| 229 | using Node = std::shared_ptr<NodeData>; | 230 | using Node = std::shared_ptr<NodeData>; |
| @@ -550,6 +551,20 @@ private: | |||
| 550 | Tegra::Shader::Register index{}; | 551 | Tegra::Shader::Register index{}; |
| 551 | }; | 552 | }; |
| 552 | 553 | ||
| 554 | /// A custom variable | ||
| 555 | class CustomVarNode final { | ||
| 556 | public: | ||
| 557 | explicit constexpr CustomVarNode(u32 index) : index{index} {} | ||
| 558 | |||
| 559 | u32 GetIndex() const { | ||
| 560 | return index; | ||
| 561 | } | ||
| 562 | |||
| 563 | private: | ||
| 564 | u32 index{}; | ||
| 565 | }; | ||
| 566 | |||
| 567 | |||
| 553 | /// A 32-bits value that represents an immediate value | 568 | /// A 32-bits value that represents an immediate value |
| 554 | class ImmediateNode final { | 569 | class ImmediateNode final { |
| 555 | public: | 570 | public: |
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index a186e22b2..94972d57f 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp | |||
| @@ -39,6 +39,10 @@ Node ShaderIR::GetRegister(Register reg) { | |||
| 39 | return MakeNode<GprNode>(reg); | 39 | return MakeNode<GprNode>(reg); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | Node ShaderIR::GetCustomVariable(u32 id) { | ||
| 43 | return MakeNode<CustomVarNode>(id); | ||
| 44 | } | ||
| 45 | |||
| 42 | Node ShaderIR::GetImmediate19(Instruction instr) { | 46 | Node ShaderIR::GetImmediate19(Instruction instr) { |
| 43 | return Immediate(instr.alu.GetImm20_19()); | 47 | return Immediate(instr.alu.GetImm20_19()); |
| 44 | } | 48 | } |
| @@ -453,4 +457,9 @@ std::size_t ShaderIR::DeclareAmend(Node new_amend) { | |||
| 453 | return id; | 457 | return id; |
| 454 | } | 458 | } |
| 455 | 459 | ||
| 460 | u32 ShaderIR::NewCustomVariable() { | ||
| 461 | const u32 id = num_custom_variables++; | ||
| 462 | return id; | ||
| 463 | } | ||
| 464 | |||
| 456 | } // namespace VideoCommon::Shader | 465 | } // namespace VideoCommon::Shader |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 121528346..2fe14e815 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -180,6 +180,10 @@ public: | |||
| 180 | return amend_code[index]; | 180 | return amend_code[index]; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | u32 GetCustomVariablesAmount() const { | ||
| 184 | return num_custom_variables; | ||
| 185 | } | ||
| 186 | |||
| 183 | private: | 187 | private: |
| 184 | friend class ASTDecoder; | 188 | friend class ASTDecoder; |
| 185 | 189 | ||
| @@ -236,6 +240,8 @@ private: | |||
| 236 | 240 | ||
| 237 | /// Generates a node for a passed register. | 241 | /// Generates a node for a passed register. |
| 238 | Node GetRegister(Tegra::Shader::Register reg); | 242 | Node GetRegister(Tegra::Shader::Register reg); |
| 243 | /// Generates a node for a custom variable | ||
| 244 | Node GetCustomVariable(u32 id); | ||
| 239 | /// Generates a node representing a 19-bit immediate value | 245 | /// Generates a node representing a 19-bit immediate value |
| 240 | Node GetImmediate19(Tegra::Shader::Instruction instr); | 246 | Node GetImmediate19(Tegra::Shader::Instruction instr); |
| 241 | /// Generates a node representing a 32-bit immediate value | 247 | /// Generates a node representing a 32-bit immediate value |
| @@ -403,6 +409,8 @@ private: | |||
| 403 | /// Register new amending code and obtain the reference id. | 409 | /// Register new amending code and obtain the reference id. |
| 404 | std::size_t DeclareAmend(Node new_amend); | 410 | std::size_t DeclareAmend(Node new_amend); |
| 405 | 411 | ||
| 412 | u32 NewCustomVariable(); | ||
| 413 | |||
| 406 | const ProgramCode& program_code; | 414 | const ProgramCode& program_code; |
| 407 | const u32 main_offset; | 415 | const u32 main_offset; |
| 408 | const CompilerSettings settings; | 416 | const CompilerSettings settings; |
| @@ -418,6 +426,7 @@ private: | |||
| 418 | NodeBlock global_code; | 426 | NodeBlock global_code; |
| 419 | ASTManager program_manager{true, true}; | 427 | ASTManager program_manager{true, true}; |
| 420 | std::vector<Node> amend_code; | 428 | std::vector<Node> amend_code; |
| 429 | u32 num_custom_variables{}; | ||
| 421 | 430 | ||
| 422 | std::set<u32> used_registers; | 431 | std::set<u32> used_registers; |
| 423 | std::set<Tegra::Shader::Pred> used_predicates; | 432 | std::set<Tegra::Shader::Pred> used_predicates; |