diff options
| author | 2021-05-09 04:01:17 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:30 -0400 | |
| commit | 939dab71202aa28b907e14876a3811dca0ed2348 (patch) | |
| tree | d0cd49930fa3e67f7a7d7ae971553af3b24bf558 /src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp | |
| parent | vk_pipeline_cache: Enable int8 and int16 types on Vulkan (diff) | |
| download | yuzu-939dab71202aa28b907e14876a3811dca0ed2348.tar.gz yuzu-939dab71202aa28b907e14876a3811dca0ed2348.tar.xz yuzu-939dab71202aa28b907e14876a3811dca0ed2348.zip | |
glasm: Implement more GLASM composite instructions
Diffstat (limited to 'src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp index 063dcaf13..94dc5019d 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp | |||
| @@ -8,60 +8,71 @@ | |||
| 8 | 8 | ||
| 9 | namespace Shader::Backend::GLASM { | 9 | namespace Shader::Backend::GLASM { |
| 10 | namespace { | 10 | namespace { |
| 11 | template <typename... Values> | 11 | template <auto read_imm, char type, typename... Values> |
| 12 | void CompositeConstructU32(EmitContext& ctx, IR::Inst& inst, Values&&... elements) { | 12 | void CompositeConstruct(EmitContext& ctx, IR::Inst& inst, Values&&... elements) { |
| 13 | const Register ret{ctx.reg_alloc.Define(inst)}; | 13 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 14 | if (std::ranges::any_of(std::array{elements...}, | 14 | if (std::ranges::any_of(std::array{elements...}, |
| 15 | [](const IR::Value& value) { return value.IsImmediate(); })) { | 15 | [](const IR::Value& value) { return value.IsImmediate(); })) { |
| 16 | const std::array<u32, 4> values{(elements.IsImmediate() ? elements.U32() : 0)...}; | 16 | using Type = std::invoke_result_t<decltype(read_imm), IR::Value>; |
| 17 | ctx.Add("MOV.U {},{{{},{},{},{}}};", ret, fmt::to_string(values[0]), | 17 | const std::array<Type, 4> values{(elements.IsImmediate() ? (elements.*read_imm)() : 0)...}; |
| 18 | ctx.Add("MOV.{} {},{{{},{},{},{}}};", type, ret, fmt::to_string(values[0]), | ||
| 18 | fmt::to_string(values[1]), fmt::to_string(values[2]), fmt::to_string(values[3])); | 19 | fmt::to_string(values[1]), fmt::to_string(values[2]), fmt::to_string(values[3])); |
| 19 | } | 20 | } |
| 20 | size_t index{}; | 21 | size_t index{}; |
| 21 | for (const IR::Value& element : {elements...}) { | 22 | for (const IR::Value& element : {elements...}) { |
| 22 | if (!element.IsImmediate()) { | 23 | if (!element.IsImmediate()) { |
| 23 | const ScalarU32 value{ctx.reg_alloc.Consume(element)}; | 24 | const ScalarU32 value{ctx.reg_alloc.Consume(element)}; |
| 24 | ctx.Add("MOV.U {}.{},{};", ret, "xyzw"[index], value); | 25 | ctx.Add("MOV.{} {}.{},{};", type, ret, "xyzw"[index], value); |
| 25 | } | 26 | } |
| 26 | ++index; | 27 | ++index; |
| 27 | } | 28 | } |
| 28 | } | 29 | } |
| 29 | 30 | ||
| 30 | void CompositeExtractU32(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { | 31 | void CompositeExtract(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index, char type) { |
| 31 | const Register ret{ctx.reg_alloc.Define(inst)}; | 32 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 32 | if (ret == composite && index == 0) { | 33 | if (ret == composite && index == 0) { |
| 33 | // No need to do anything here, the source and destination are the same register | 34 | // No need to do anything here, the source and destination are the same register |
| 34 | return; | 35 | return; |
| 35 | } | 36 | } |
| 36 | ctx.Add("MOV.U {}.x,{}.{};", ret, composite, "xyzw"[index]); | 37 | ctx.Add("MOV.{} {}.x,{}.{};", type, ret, composite, "xyzw"[index]); |
| 38 | } | ||
| 39 | |||
| 40 | template <typename ObjectType> | ||
| 41 | void CompositeInsert(EmitContext& ctx, IR::Inst& inst, Register composite, ObjectType object, | ||
| 42 | u32 index, char type) { | ||
| 43 | const Register ret{ctx.reg_alloc.Define(inst)}; | ||
| 44 | if (ret != composite) { | ||
| 45 | ctx.Add("MOV.{} {},{};", type, ret, composite); | ||
| 46 | } | ||
| 47 | ctx.Add("MOV.{} {}.{},{};", type, ret, "xyzw"[index], object); | ||
| 37 | } | 48 | } |
| 38 | } // Anonymous namespace | 49 | } // Anonymous namespace |
| 39 | 50 | ||
| 40 | void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, | 51 | void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, |
| 41 | const IR::Value& e2) { | 52 | const IR::Value& e2) { |
| 42 | CompositeConstructU32(ctx, inst, e1, e2); | 53 | CompositeConstruct<&IR::Value::U32, 'U'>(ctx, inst, e1, e2); |
| 43 | } | 54 | } |
| 44 | 55 | ||
| 45 | void EmitCompositeConstructU32x3(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, | 56 | void EmitCompositeConstructU32x3(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, |
| 46 | const IR::Value& e2, const IR::Value& e3) { | 57 | const IR::Value& e2, const IR::Value& e3) { |
| 47 | CompositeConstructU32(ctx, inst, e1, e2, e3); | 58 | CompositeConstruct<&IR::Value::U32, 'U'>(ctx, inst, e1, e2, e3); |
| 48 | } | 59 | } |
| 49 | 60 | ||
| 50 | void EmitCompositeConstructU32x4(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, | 61 | void EmitCompositeConstructU32x4(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, |
| 51 | const IR::Value& e2, const IR::Value& e3, const IR::Value& e4) { | 62 | const IR::Value& e2, const IR::Value& e3, const IR::Value& e4) { |
| 52 | CompositeConstructU32(ctx, inst, e1, e2, e3, e4); | 63 | CompositeConstruct<&IR::Value::U32, 'U'>(ctx, inst, e1, e2, e3, e4); |
| 53 | } | 64 | } |
| 54 | 65 | ||
| 55 | void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { | 66 | void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { |
| 56 | CompositeExtractU32(ctx, inst, composite, index); | 67 | CompositeExtract(ctx, inst, composite, index, 'U'); |
| 57 | } | 68 | } |
| 58 | 69 | ||
| 59 | void EmitCompositeExtractU32x3(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { | 70 | void EmitCompositeExtractU32x3(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { |
| 60 | CompositeExtractU32(ctx, inst, composite, index); | 71 | CompositeExtract(ctx, inst, composite, index, 'U'); |
| 61 | } | 72 | } |
| 62 | 73 | ||
| 63 | void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { | 74 | void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { |
| 64 | CompositeExtractU32(ctx, inst, composite, index); | 75 | CompositeExtract(ctx, inst, composite, index, 'U'); |
| 65 | } | 76 | } |
| 66 | 77 | ||
| 67 | void EmitCompositeInsertU32x2([[maybe_unused]] EmitContext& ctx, | 78 | void EmitCompositeInsertU32x2([[maybe_unused]] EmitContext& ctx, |
| @@ -131,53 +142,46 @@ void EmitCompositeInsertF16x4([[maybe_unused]] EmitContext& ctx, | |||
| 131 | throw NotImplementedException("GLASM instruction"); | 142 | throw NotImplementedException("GLASM instruction"); |
| 132 | } | 143 | } |
| 133 | 144 | ||
| 134 | void EmitCompositeConstructF32x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 e1, | 145 | void EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, |
| 135 | [[maybe_unused]] ScalarF32 e2) { | 146 | const IR::Value& e2) { |
| 136 | throw NotImplementedException("GLASM instruction"); | 147 | CompositeConstruct<&IR::Value::F32, 'F'>(ctx, inst, e1, e2); |
| 137 | } | 148 | } |
| 138 | 149 | ||
| 139 | void EmitCompositeConstructF32x3([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 e1, | 150 | void EmitCompositeConstructF32x3(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, |
| 140 | [[maybe_unused]] ScalarF32 e2, [[maybe_unused]] ScalarF32 e3) { | 151 | const IR::Value& e2, const IR::Value& e3) { |
| 141 | throw NotImplementedException("GLASM instruction"); | 152 | CompositeConstruct<&IR::Value::F32, 'F'>(ctx, inst, e1, e2, e3); |
| 142 | } | 153 | } |
| 143 | 154 | ||
| 144 | void EmitCompositeConstructF32x4([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 e1, | 155 | void EmitCompositeConstructF32x4(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, |
| 145 | [[maybe_unused]] ScalarF32 e2, [[maybe_unused]] ScalarF32 e3, | 156 | const IR::Value& e2, const IR::Value& e3, const IR::Value& e4) { |
| 146 | [[maybe_unused]] ScalarF32 e4) { | 157 | CompositeConstruct<&IR::Value::F32, 'F'>(ctx, inst, e1, e2, e3, e4); |
| 147 | throw NotImplementedException("GLASM instruction"); | ||
| 148 | } | 158 | } |
| 149 | 159 | ||
| 150 | void EmitCompositeExtractF32x2([[maybe_unused]] EmitContext& ctx, | 160 | void EmitCompositeExtractF32x2(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { |
| 151 | [[maybe_unused]] Register composite, [[maybe_unused]] u32 index) { | 161 | CompositeExtract(ctx, inst, composite, index, 'F'); |
| 152 | throw NotImplementedException("GLASM instruction"); | ||
| 153 | } | 162 | } |
| 154 | 163 | ||
| 155 | void EmitCompositeExtractF32x3([[maybe_unused]] EmitContext& ctx, | 164 | void EmitCompositeExtractF32x3(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { |
| 156 | [[maybe_unused]] Register composite, [[maybe_unused]] u32 index) { | 165 | CompositeExtract(ctx, inst, composite, index, 'F'); |
| 157 | throw NotImplementedException("GLASM instruction"); | ||
| 158 | } | 166 | } |
| 159 | 167 | ||
| 160 | void EmitCompositeExtractF32x4([[maybe_unused]] EmitContext& ctx, | 168 | void EmitCompositeExtractF32x4(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { |
| 161 | [[maybe_unused]] Register composite, [[maybe_unused]] u32 index) { | 169 | CompositeExtract(ctx, inst, composite, index, 'F'); |
| 162 | throw NotImplementedException("GLASM instruction"); | ||
| 163 | } | 170 | } |
| 164 | 171 | ||
| 165 | void EmitCompositeInsertF32x2([[maybe_unused]] EmitContext& ctx, | 172 | void EmitCompositeInsertF32x2(EmitContext& ctx, IR::Inst& inst, Register composite, |
| 166 | [[maybe_unused]] Register composite, | 173 | ScalarF32 object, u32 index) { |
| 167 | [[maybe_unused]] ScalarF32 object, [[maybe_unused]] u32 index) { | 174 | CompositeInsert(ctx, inst, composite, object, index, 'F'); |
| 168 | throw NotImplementedException("GLASM instruction"); | ||
| 169 | } | 175 | } |
| 170 | 176 | ||
| 171 | void EmitCompositeInsertF32x3([[maybe_unused]] EmitContext& ctx, | 177 | void EmitCompositeInsertF32x3(EmitContext& ctx, IR::Inst& inst, Register composite, |
| 172 | [[maybe_unused]] Register composite, | 178 | ScalarF32 object, u32 index) { |
| 173 | [[maybe_unused]] ScalarF32 object, [[maybe_unused]] u32 index) { | 179 | CompositeInsert(ctx, inst, composite, object, index, 'F'); |
| 174 | throw NotImplementedException("GLASM instruction"); | ||
| 175 | } | 180 | } |
| 176 | 181 | ||
| 177 | void EmitCompositeInsertF32x4([[maybe_unused]] EmitContext& ctx, | 182 | void EmitCompositeInsertF32x4(EmitContext& ctx, IR::Inst& inst, Register composite, |
| 178 | [[maybe_unused]] Register composite, | 183 | ScalarF32 object, u32 index) { |
| 179 | [[maybe_unused]] ScalarF32 object, [[maybe_unused]] u32 index) { | 184 | CompositeInsert(ctx, inst, composite, object, index, 'F'); |
| 180 | throw NotImplementedException("GLASM instruction"); | ||
| 181 | } | 185 | } |
| 182 | 186 | ||
| 183 | void EmitCompositeConstructF64x2([[maybe_unused]] EmitContext& ctx) { | 187 | void EmitCompositeConstructF64x2([[maybe_unused]] EmitContext& ctx) { |