diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-03-14 06:27:06 +0100 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-04-10 19:20:25 +0200 |
commit | ca51f9984076ec99ce463f9804ed4bcaa644e285 (patch) | |
tree | e3dbd6d766f769143e70bbc9d0092b0ee8507860 /src/video_core | |
parent | vk_shader_decompiler: Implement declarations (diff) | |
download | yuzu-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.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: 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) { |