diff options
| author | 2019-03-14 02:27:06 -0300 | |
|---|---|---|
| committer | 2019-04-10 14:20:25 -0300 | |
| commit | ca51f9984076ec99ce463f9804ed4bcaa644e285 (patch) | |
| tree | e3dbd6d766f769143e70bbc9d0092b0ee8507860 /src | |
| parent | vk_shader_decompiler: Implement declarations (diff) | |
| download | yuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.tar.gz yuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.tar.xz yuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.zip | |
vk_shader_decompiler: Implement labels tree and flow
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 563b3eb51..7af8e79df 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -86,6 +86,7 @@ public: | |||
| 86 | 86 | ||
| 87 | void Decompile() { | 87 | void Decompile() { |
| 88 | AllocateBindings(); | 88 | AllocateBindings(); |
| 89 | AllocateLabels(); | ||
| 89 | 90 | ||
| 90 | DeclareVertex(); | 91 | DeclareVertex(); |
| 91 | DeclareGeometry(); | 92 | DeclareGeometry(); |
| @@ -100,7 +101,63 @@ public: | |||
| 100 | DeclareGlobalBuffers(); | 101 | DeclareGlobalBuffers(); |
| 101 | DeclareSamplers(); | 102 | DeclareSamplers(); |
| 102 | 103 | ||
| 104 | execute_function = | ||
| 105 | Emit(OpFunction(t_void, spv::FunctionControlMask::Inline, TypeFunction(t_void))); | ||
| 106 | Emit(OpLabel()); | ||
| 107 | |||
| 108 | const u32 first_address = ir.GetBasicBlocks().begin()->first; | ||
| 109 | const Id loop_label = OpLabel("loop"); | ||
| 110 | const Id merge_label = OpLabel("merge"); | ||
| 111 | const Id dummy_label = OpLabel(); | ||
| 112 | const Id jump_label = OpLabel(); | ||
| 113 | continue_label = OpLabel("continue"); | ||
| 114 | |||
| 115 | std::vector<Sirit::Literal> literals; | ||
| 116 | std::vector<Id> branch_labels; | ||
| 117 | for (const auto& pair : labels) { | ||
| 118 | const auto [literal, label] = pair; | ||
| 119 | literals.push_back(literal); | ||
| 120 | branch_labels.push_back(label); | ||
| 121 | } | ||
| 122 | |||
| 123 | // TODO(Rodrigo): Figure out the actual depth of the flow stack, for now it seems unlikely | ||
| 124 | // that shaders will use 20 nested SSYs and PBKs. | ||
| 125 | constexpr u32 FLOW_STACK_SIZE = 20; | ||
| 126 | const Id flow_stack_type = TypeArray(t_uint, Constant(t_uint, FLOW_STACK_SIZE)); | ||
| 127 | jmp_to = Emit(OpVariable(TypePointer(spv::StorageClass::Function, t_uint), | ||
| 128 | spv::StorageClass::Function, Constant(t_uint, first_address))); | ||
| 129 | flow_stack = Emit(OpVariable(TypePointer(spv::StorageClass::Function, flow_stack_type), | ||
| 130 | spv::StorageClass::Function, ConstantNull(flow_stack_type))); | ||
| 131 | flow_stack_top = | ||
| 132 | Emit(OpVariable(t_func_uint, spv::StorageClass::Function, Constant(t_uint, 0))); | ||
| 133 | |||
| 134 | Name(jmp_to, "jmp_to"); | ||
| 135 | Name(flow_stack, "flow_stack"); | ||
| 136 | Name(flow_stack_top, "flow_stack_top"); | ||
| 137 | |||
| 138 | Emit(OpBranch(loop_label)); | ||
| 139 | Emit(loop_label); | ||
| 140 | Emit(OpLoopMerge(merge_label, continue_label, spv::LoopControlMask::Unroll)); | ||
| 141 | Emit(OpBranch(dummy_label)); | ||
| 142 | |||
| 143 | Emit(dummy_label); | ||
| 144 | const Id default_branch = OpLabel(); | ||
| 145 | const Id jmp_to_load = Emit(OpLoad(t_uint, jmp_to)); | ||
| 146 | Emit(OpSelectionMerge(jump_label, spv::SelectionControlMask::MaskNone)); | ||
| 147 | Emit(OpSwitch(jmp_to_load, default_branch, literals, branch_labels)); | ||
| 148 | |||
| 149 | Emit(default_branch); | ||
| 150 | Emit(OpReturn()); | ||
| 151 | |||
| 103 | UNIMPLEMENTED(); | 152 | UNIMPLEMENTED(); |
| 153 | |||
| 154 | Emit(jump_label); | ||
| 155 | Emit(OpBranch(continue_label)); | ||
| 156 | Emit(continue_label); | ||
| 157 | Emit(OpBranch(loop_label)); | ||
| 158 | Emit(merge_label); | ||
| 159 | Emit(OpReturn()); | ||
| 160 | Emit(OpFunctionEnd()); | ||
| 104 | } | 161 | } |
| 105 | 162 | ||
| 106 | ShaderEntries GetShaderEntries() const { | 163 | ShaderEntries GetShaderEntries() const { |
| @@ -148,6 +205,13 @@ private: | |||
| 148 | "Stage binding stride is too small"); | 205 | "Stage binding stride is too small"); |
| 149 | } | 206 | } |
| 150 | 207 | ||
| 208 | void AllocateLabels() { | ||
| 209 | for (const auto& pair : ir.GetBasicBlocks()) { | ||
| 210 | const u32 address = pair.first; | ||
| 211 | labels.emplace(address, OpLabel(fmt::format("label_0x{:x}", address))); | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 151 | void DeclareVertex() { | 215 | void DeclareVertex() { |
| 152 | if (stage != ShaderStage::Vertex) | 216 | if (stage != ShaderStage::Vertex) |
| 153 | return; | 217 | return; |
| @@ -432,6 +496,8 @@ private: | |||
| 432 | const Id t_prv_bool = Name(TypePointer(spv::StorageClass::Private, t_bool), "prv_bool"); | 496 | const Id t_prv_bool = Name(TypePointer(spv::StorageClass::Private, t_bool), "prv_bool"); |
| 433 | const Id t_prv_float = Name(TypePointer(spv::StorageClass::Private, t_float), "prv_float"); | 497 | const Id t_prv_float = Name(TypePointer(spv::StorageClass::Private, t_float), "prv_float"); |
| 434 | 498 | ||
| 499 | const Id t_func_uint = Name(TypePointer(spv::StorageClass::Function, t_uint), "func_uint"); | ||
| 500 | |||
| 435 | const Id t_in_bool = Name(TypePointer(spv::StorageClass::Input, t_bool), "in_bool"); | 501 | const Id t_in_bool = Name(TypePointer(spv::StorageClass::Input, t_bool), "in_bool"); |
| 436 | const Id t_in_uint = Name(TypePointer(spv::StorageClass::Input, t_uint), "in_uint"); | 502 | const Id t_in_uint = Name(TypePointer(spv::StorageClass::Input, t_uint), "in_uint"); |
| 437 | const Id t_in_float = Name(TypePointer(spv::StorageClass::Input, t_float), "in_float"); | 503 | const Id t_in_float = Name(TypePointer(spv::StorageClass::Input, t_float), "in_float"); |
| @@ -488,6 +554,11 @@ private: | |||
| 488 | u32 samplers_base_binding{}; | 554 | u32 samplers_base_binding{}; |
| 489 | 555 | ||
| 490 | Id execute_function{}; | 556 | Id execute_function{}; |
| 557 | Id jmp_to{}; | ||
| 558 | Id flow_stack_top{}; | ||
| 559 | Id flow_stack{}; | ||
| 560 | Id continue_label{}; | ||
| 561 | std::map<u32, Id> labels; | ||
| 491 | }; | 562 | }; |
| 492 | 563 | ||
| 493 | DecompilerResult Decompile(const VideoCommon::Shader::ShaderIR& ir, Maxwell::ShaderStage stage) { | 564 | DecompilerResult Decompile(const VideoCommon::Shader::ShaderIR& ir, Maxwell::ShaderStage stage) { |