summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-02-24 18:37:47 -0300
committerGravatar ameerj2021-07-22 21:51:22 -0400
commit726625cf5057157fb5e4c9c210676930ff520dd2 (patch)
tree5a147ce1419c01e643e36adf405f04b2729c898e /src/shader_recompiler/backend
parentshader: Avoid infinite recursion when tracking global memory (diff)
downloadyuzu-726625cf5057157fb5e4c9c210676930ff520dd2.tar.gz
yuzu-726625cf5057157fb5e4c9c210676930ff520dd2.tar.xz
yuzu-726625cf5057157fb5e4c9c210676930ff520dd2.zip
spirv: Move phi arguments emit to a separate function
Diffstat (limited to 'src/shader_recompiler/backend')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp54
1 files changed, 27 insertions, 27 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
index bcd6bda28..8097fe82d 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
@@ -163,6 +163,31 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit
163 } 163 }
164 } 164 }
165} 165}
166
167Id PhiArgDef(EmitContext& ctx, IR::Inst* inst, size_t index) {
168 // Phi nodes can have forward declarations, if an argument is not defined provide a forward
169 // declaration of it. Invoke will take care of giving it the right definition when it's
170 // actually defined.
171 const IR::Value arg{inst->Arg(index)};
172 if (arg.IsImmediate()) {
173 // Let the context handle immediate definitions, as it already knows how
174 return ctx.Def(arg);
175 }
176 IR::Inst* const arg_inst{arg.Inst()};
177 if (const Id def{arg_inst->Definition<Id>()}; Sirit::ValidId(def)) {
178 // Return the current definition if it exists
179 return def;
180 }
181 if (arg_inst == inst) {
182 // This is a self referencing phi node
183 // Self-referencing definition will be set by the caller, so just grab the current id
184 return ctx.CurrentId();
185 }
186 // If it hasn't been defined and it's not a self reference, get a forward declaration
187 const Id def{ctx.ForwardDeclarationId()};
188 arg_inst->SetDefinition<Id>(def);
189 return def;
190}
166} // Anonymous namespace 191} // Anonymous namespace
167 192
168std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program& program) { 193std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program& program) {
@@ -205,33 +230,8 @@ Id EmitPhi(EmitContext& ctx, IR::Inst* inst) {
205 boost::container::small_vector<Id, 32> operands; 230 boost::container::small_vector<Id, 32> operands;
206 operands.reserve(num_args * 2); 231 operands.reserve(num_args * 2);
207 for (size_t index = 0; index < num_args; ++index) { 232 for (size_t index = 0; index < num_args; ++index) {
208 // Phi nodes can have forward declarations, if an argument is not defined provide a forward 233 operands.push_back(PhiArgDef(ctx, inst, index));
209 // declaration of it. Invoke will take care of giving it the right definition when it's 234 operands.push_back(inst->PhiBlock(index)->Definition<Id>());
210 // actually defined.
211 const IR::Value arg{inst->Arg(index)};
212 Id def{};
213 if (arg.IsImmediate()) {
214 // Let the context handle immediate definitions, as it already knows how
215 def = ctx.Def(arg);
216 } else {
217 IR::Inst* const arg_inst{arg.Inst()};
218 def = arg_inst->Definition<Id>();
219 if (!Sirit::ValidId(def)) {
220 if (arg_inst == inst) {
221 // This is a self referencing phi node
222 def = ctx.CurrentId();
223 // Self-referencing definition will be set by the caller
224 } else {
225 // If it hasn't been defined and it's not a self reference,
226 // get a forward declaration
227 def = ctx.ForwardDeclarationId();
228 arg_inst->SetDefinition<Id>(def);
229 }
230 }
231 }
232 IR::Block* const phi_block{inst->PhiBlock(index)};
233 operands.push_back(def);
234 operands.push_back(phi_block->Definition<Id>());
235 } 235 }
236 const Id result_type{TypeId(ctx, inst->Arg(0).Type())}; 236 const Id result_type{TypeId(ctx, inst->Arg(0).Type())};
237 return ctx.OpPhi(result_type, std::span(operands.data(), operands.size())); 237 return ctx.OpPhi(result_type, std::span(operands.data(), operands.size()));