summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-03-14 06:27:06 +0100
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-04-10 19:20:25 +0200
commitca51f9984076ec99ce463f9804ed4bcaa644e285 (patch)
treee3dbd6d766f769143e70bbc9d0092b0ee8507860 /src/video_core
parentvk_shader_decompiler: Implement declarations (diff)
downloadyuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.tar
yuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.tar.gz
yuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.tar.bz2
yuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.tar.lz
yuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.tar.xz
yuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.tar.zst
yuzu-ca51f9984076ec99ce463f9804ed4bcaa644e285.zip
Diffstat (limited to 'src/video_core')
-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:
void Decompile() {
AllocateBindings();
+ AllocateLabels();
DeclareVertex();
DeclareGeometry();
@@ -100,7 +101,63 @@ public:
DeclareGlobalBuffers();
DeclareSamplers();
+ execute_function =
+ Emit(OpFunction(t_void, spv::FunctionControlMask::Inline, TypeFunction(t_void)));
+ Emit(OpLabel());
+
+ const u32 first_address = ir.GetBasicBlocks().begin()->first;
+ const Id loop_label = OpLabel("loop");
+ const Id merge_label = OpLabel("merge");
+ const Id dummy_label = OpLabel();
+ const Id jump_label = OpLabel();
+ continue_label = OpLabel("continue");
+
+ std::vector<Sirit::Literal> literals;
+ std::vector<Id> branch_labels;
+ for (const auto& pair : labels) {
+ const auto [literal, label] = pair;
+ literals.push_back(literal);
+ branch_labels.push_back(label);
+ }
+
+ // TODO(Rodrigo): Figure out the actual depth of the flow stack, for now it seems unlikely
+ // that shaders will use 20 nested SSYs and PBKs.
+ constexpr u32 FLOW_STACK_SIZE = 20;
+ const Id flow_stack_type = TypeArray(t_uint, Constant(t_uint, FLOW_STACK_SIZE));
+ jmp_to = Emit(OpVariable(TypePointer(spv::StorageClass::Function, t_uint),
+ spv::StorageClass::Function, Constant(t_uint, first_address)));
+ flow_stack = Emit(OpVariable(TypePointer(spv::StorageClass::Function, flow_stack_type),
+ spv::StorageClass::Function, ConstantNull(flow_stack_type)));
+ flow_stack_top =
+ Emit(OpVariable(t_func_uint, spv::StorageClass::Function, Constant(t_uint, 0)));
+
+ Name(jmp_to, "jmp_to");
+ Name(flow_stack, "flow_stack");
+ Name(flow_stack_top, "flow_stack_top");
+
+ Emit(OpBranch(loop_label));
+ Emit(loop_label);
+ Emit(OpLoopMerge(merge_label, continue_label, spv::LoopControlMask::Unroll));
+ Emit(OpBranch(dummy_label));
+
+ Emit(dummy_label);
+ const Id default_branch = OpLabel();
+ const Id jmp_to_load = Emit(OpLoad(t_uint, jmp_to));
+ Emit(OpSelectionMerge(jump_label, spv::SelectionControlMask::MaskNone));
+ Emit(OpSwitch(jmp_to_load, default_branch, literals, branch_labels));
+
+ Emit(default_branch);
+ Emit(OpReturn());
+
UNIMPLEMENTED();
+
+ Emit(jump_label);
+ Emit(OpBranch(continue_label));
+ Emit(continue_label);
+ Emit(OpBranch(loop_label));
+ Emit(merge_label);
+ Emit(OpReturn());
+ Emit(OpFunctionEnd());
}
ShaderEntries GetShaderEntries() const {
@@ -148,6 +205,13 @@ private:
"Stage binding stride is too small");
}
+ void AllocateLabels() {
+ for (const auto& pair : ir.GetBasicBlocks()) {
+ const u32 address = pair.first;
+ labels.emplace(address, OpLabel(fmt::format("label_0x{:x}", address)));
+ }
+ }
+
void DeclareVertex() {
if (stage != ShaderStage::Vertex)
return;
@@ -432,6 +496,8 @@ private:
const Id t_prv_bool = Name(TypePointer(spv::StorageClass::Private, t_bool), "prv_bool");
const Id t_prv_float = Name(TypePointer(spv::StorageClass::Private, t_float), "prv_float");
+ const Id t_func_uint = Name(TypePointer(spv::StorageClass::Function, t_uint), "func_uint");
+
const Id t_in_bool = Name(TypePointer(spv::StorageClass::Input, t_bool), "in_bool");
const Id t_in_uint = Name(TypePointer(spv::StorageClass::Input, t_uint), "in_uint");
const Id t_in_float = Name(TypePointer(spv::StorageClass::Input, t_float), "in_float");
@@ -488,6 +554,11 @@ private:
u32 samplers_base_binding{};
Id execute_function{};
+ Id jmp_to{};
+ Id flow_stack_top{};
+ Id flow_stack{};
+ Id continue_label{};
+ std::map<u32, Id> labels;
};
DecompilerResult Decompile(const VideoCommon::Shader::ShaderIR& ir, Maxwell::ShaderStage stage) {