summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-03-14 02:27:06 -0300
committerGravatar ReinUsesLisp2019-04-10 14:20:25 -0300
commitca51f9984076ec99ce463f9804ed4bcaa644e285 (patch)
treee3dbd6d766f769143e70bbc9d0092b0ee8507860 /src
parentvk_shader_decompiler: Implement declarations (diff)
downloadyuzu-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.cpp71
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
493DecompilerResult Decompile(const VideoCommon::Shader::ShaderIR& ir, Maxwell::ShaderStage stage) { 564DecompilerResult Decompile(const VideoCommon::Shader::ShaderIR& ir, Maxwell::ShaderStage stage) {