diff options
| author | 2021-02-24 18:37:47 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:22 -0400 | |
| commit | 726625cf5057157fb5e4c9c210676930ff520dd2 (patch) | |
| tree | 5a147ce1419c01e643e36adf405f04b2729c898e /src/shader_recompiler/backend | |
| parent | shader: Avoid infinite recursion when tracking global memory (diff) | |
| download | yuzu-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.cpp | 54 |
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 | |||
| 167 | Id 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 | ||
| 168 | std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program& program) { | 193 | std::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())); |