diff options
| author | 2021-05-14 00:40:54 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:31 -0400 | |
| commit | d54d7de40e7295827b0e4e4026441b53d3fc9569 (patch) | |
| tree | 29b5074f851292dace7aeb5da7716675544b3735 /src/shader_recompiler/backend/spirv/emit_spirv.cpp | |
| parent | glasm: Implement Storage atomics (diff) | |
| download | yuzu-d54d7de40e7295827b0e4e4026441b53d3fc9569.tar.gz yuzu-d54d7de40e7295827b0e4e4026441b53d3fc9569.tar.xz yuzu-d54d7de40e7295827b0e4e4026441b53d3fc9569.zip | |
glasm: Rework control flow introducing a syntax list
This commit regresses VertexA shaders, their transformation pass has to
be adapted to the new control flow.
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv.cpp | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 2dad87e87..c22edfec2 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -41,8 +41,6 @@ ArgType Arg(EmitContext& ctx, const IR::Value& arg) { | |||
| 41 | return arg; | 41 | return arg; |
| 42 | } else if constexpr (std::is_same_v<ArgType, u32>) { | 42 | } else if constexpr (std::is_same_v<ArgType, u32>) { |
| 43 | return arg.U32(); | 43 | return arg.U32(); |
| 44 | } else if constexpr (std::is_same_v<ArgType, IR::Block*>) { | ||
| 45 | return arg.Label(); | ||
| 46 | } else if constexpr (std::is_same_v<ArgType, IR::Attribute>) { | 44 | } else if constexpr (std::is_same_v<ArgType, IR::Attribute>) { |
| 47 | return arg.Attribute(); | 45 | return arg.Attribute(); |
| 48 | } else if constexpr (std::is_same_v<ArgType, IR::Patch>) { | 46 | } else if constexpr (std::is_same_v<ArgType, IR::Patch>) { |
| @@ -109,15 +107,74 @@ Id TypeId(const EmitContext& ctx, IR::Type type) { | |||
| 109 | } | 107 | } |
| 110 | } | 108 | } |
| 111 | 109 | ||
| 110 | void Traverse(EmitContext& ctx, IR::Program& program) { | ||
| 111 | IR::Block* current_block{}; | ||
| 112 | for (const IR::AbstractSyntaxNode& node : program.syntax_list) { | ||
| 113 | switch (node.type) { | ||
| 114 | case IR::AbstractSyntaxNode::Type::Block: | ||
| 115 | const Id label{node.block->Definition<Id>()}; | ||
| 116 | if (current_block) { | ||
| 117 | ctx.OpBranch(label); | ||
| 118 | } | ||
| 119 | current_block = node.block; | ||
| 120 | ctx.AddLabel(label); | ||
| 121 | for (IR::Inst& inst : node.block->Instructions()) { | ||
| 122 | EmitInst(ctx, &inst); | ||
| 123 | } | ||
| 124 | break; | ||
| 125 | case IR::AbstractSyntaxNode::Type::If: { | ||
| 126 | const Id if_label{node.if_node.body->Definition<Id>()}; | ||
| 127 | const Id endif_label{node.if_node.merge->Definition<Id>()}; | ||
| 128 | ctx.OpSelectionMerge(endif_label, spv::SelectionControlMask::MaskNone); | ||
| 129 | ctx.OpBranchConditional(ctx.Def(node.if_node.cond), if_label, endif_label); | ||
| 130 | break; | ||
| 131 | } | ||
| 132 | case IR::AbstractSyntaxNode::Type::Loop: { | ||
| 133 | const Id body_label{node.loop.body->Definition<Id>()}; | ||
| 134 | const Id continue_label{node.loop.continue_block->Definition<Id>()}; | ||
| 135 | const Id endloop_label{node.loop.merge->Definition<Id>()}; | ||
| 136 | |||
| 137 | ctx.OpLoopMerge(endloop_label, continue_label, spv::LoopControlMask::MaskNone); | ||
| 138 | ctx.OpBranch(node.loop.body->Definition<Id>()); | ||
| 139 | break; | ||
| 140 | } | ||
| 141 | case IR::AbstractSyntaxNode::Type::Break: { | ||
| 142 | const Id break_label{node.break_node.merge->Definition<Id>()}; | ||
| 143 | const Id skip_label{node.break_node.skip->Definition<Id>()}; | ||
| 144 | ctx.OpBranchConditional(ctx.Def(node.break_node.cond), break_label, skip_label); | ||
| 145 | break; | ||
| 146 | } | ||
| 147 | case IR::AbstractSyntaxNode::Type::EndIf: | ||
| 148 | if (current_block) { | ||
| 149 | ctx.OpBranch(node.end_if.merge->Definition<Id>()); | ||
| 150 | } | ||
| 151 | break; | ||
| 152 | case IR::AbstractSyntaxNode::Type::Repeat: { | ||
| 153 | const Id loop_header_label{node.repeat.loop_header->Definition<Id>()}; | ||
| 154 | const Id merge_label{node.repeat.merge->Definition<Id>()}; | ||
| 155 | ctx.OpBranchConditional(ctx.Def(node.repeat.cond), loop_header_label, merge_label); | ||
| 156 | break; | ||
| 157 | } | ||
| 158 | case IR::AbstractSyntaxNode::Type::Return: | ||
| 159 | ctx.OpReturn(); | ||
| 160 | break; | ||
| 161 | case IR::AbstractSyntaxNode::Type::Unreachable: | ||
| 162 | ctx.OpUnreachable(); | ||
| 163 | break; | ||
| 164 | } | ||
| 165 | if (node.type != IR::AbstractSyntaxNode::Type::Block) { | ||
| 166 | current_block = nullptr; | ||
| 167 | } | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 112 | Id DefineMain(EmitContext& ctx, IR::Program& program) { | 171 | Id DefineMain(EmitContext& ctx, IR::Program& program) { |
| 113 | const Id void_function{ctx.TypeFunction(ctx.void_id)}; | 172 | const Id void_function{ctx.TypeFunction(ctx.void_id)}; |
| 114 | const Id main{ctx.OpFunction(ctx.void_id, spv::FunctionControlMask::MaskNone, void_function)}; | 173 | const Id main{ctx.OpFunction(ctx.void_id, spv::FunctionControlMask::MaskNone, void_function)}; |
| 115 | for (IR::Block* const block : program.blocks) { | 174 | for (IR::Block* const block : program.blocks) { |
| 116 | ctx.AddLabel(block->Definition<Id>()); | 175 | block->SetDefinition(ctx.OpLabel()); |
| 117 | for (IR::Inst& inst : block->Instructions()) { | ||
| 118 | EmitInst(ctx, &inst); | ||
| 119 | } | ||
| 120 | } | 176 | } |
| 177 | Traverse(ctx, program); | ||
| 121 | ctx.OpFunctionEnd(); | 178 | ctx.OpFunctionEnd(); |
| 122 | return main; | 179 | return main; |
| 123 | } | 180 | } |
| @@ -411,6 +468,8 @@ Id EmitIdentity(EmitContext& ctx, const IR::Value& value) { | |||
| 411 | return id; | 468 | return id; |
| 412 | } | 469 | } |
| 413 | 470 | ||
| 471 | void EmitBranchConditionRef(EmitContext&) {} | ||
| 472 | |||
| 414 | void EmitGetZeroFromOp(EmitContext&) { | 473 | void EmitGetZeroFromOp(EmitContext&) { |
| 415 | throw LogicError("Unreachable instruction"); | 474 | throw LogicError("Unreachable instruction"); |
| 416 | } | 475 | } |