summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/emit_spirv.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-14 00:40:54 -0300
committerGravatar ameerj2021-07-22 21:51:31 -0400
commitd54d7de40e7295827b0e4e4026441b53d3fc9569 (patch)
tree29b5074f851292dace7aeb5da7716675544b3735 /src/shader_recompiler/backend/spirv/emit_spirv.cpp
parentglasm: Implement Storage atomics (diff)
downloadyuzu-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.cpp71
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
110void 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
112Id DefineMain(EmitContext& ctx, IR::Program& program) { 171Id 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
471void EmitBranchConditionRef(EmitContext&) {}
472
414void EmitGetZeroFromOp(EmitContext&) { 473void EmitGetZeroFromOp(EmitContext&) {
415 throw LogicError("Unreachable instruction"); 474 throw LogicError("Unreachable instruction");
416} 475}