diff options
| author | 2021-02-11 16:39:06 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:22 -0400 | |
| commit | 9170200a11715d131645d1ffb92e86e6ef0d7e88 (patch) | |
| tree | 6c6f84c38a9b59d023ecb09c0737ea56da166b64 /src/shader_recompiler/backend | |
| parent | spirv: Initial SPIR-V support (diff) | |
| download | yuzu-9170200a11715d131645d1ffb92e86e6ef0d7e88.tar.gz yuzu-9170200a11715d131645d1ffb92e86e6ef0d7e88.tar.xz yuzu-9170200a11715d131645d1ffb92e86e6ef0d7e88.zip | |
shader: Initial implementation of an AST
Diffstat (limited to 'src/shader_recompiler/backend')
5 files changed, 67 insertions, 41 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 7c4269fad..5022b5159 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -105,8 +105,26 @@ void EmitSPIRV::EmitInst(EmitContext& ctx, IR::Inst* inst) { | |||
| 105 | throw LogicError("Invalid opcode {}", inst->Opcode()); | 105 | throw LogicError("Invalid opcode {}", inst->Opcode()); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | void EmitSPIRV::EmitPhi(EmitContext&) { | 108 | static Id TypeId(const EmitContext& ctx, IR::Type type) { |
| 109 | throw NotImplementedException("SPIR-V Instruction"); | 109 | switch (type) { |
| 110 | case IR::Type::U1: | ||
| 111 | return ctx.u1; | ||
| 112 | default: | ||
| 113 | throw NotImplementedException("Phi node type {}", type); | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | Id EmitSPIRV::EmitPhi(EmitContext& ctx, IR::Inst* inst) { | ||
| 118 | const size_t num_args{inst->NumArgs()}; | ||
| 119 | boost::container::small_vector<Id, 64> operands; | ||
| 120 | operands.reserve(num_args * 2); | ||
| 121 | for (size_t index = 0; index < num_args; ++index) { | ||
| 122 | IR::Block* const phi_block{inst->PhiBlock(index)}; | ||
| 123 | operands.push_back(ctx.Def(inst->Arg(index))); | ||
| 124 | operands.push_back(ctx.BlockLabel(phi_block)); | ||
| 125 | } | ||
| 126 | const Id result_type{TypeId(ctx, inst->Arg(0).Type())}; | ||
| 127 | return ctx.OpPhi(result_type, std::span(operands.data(), operands.size())); | ||
| 110 | } | 128 | } |
| 111 | 129 | ||
| 112 | void EmitSPIRV::EmitVoid(EmitContext&) {} | 130 | void EmitSPIRV::EmitVoid(EmitContext&) {} |
| @@ -115,6 +133,29 @@ void EmitSPIRV::EmitIdentity(EmitContext&) { | |||
| 115 | throw NotImplementedException("SPIR-V Instruction"); | 133 | throw NotImplementedException("SPIR-V Instruction"); |
| 116 | } | 134 | } |
| 117 | 135 | ||
| 136 | // FIXME: Move to its own file | ||
| 137 | void EmitSPIRV::EmitBranch(EmitContext& ctx, IR::Inst* inst) { | ||
| 138 | ctx.OpBranch(ctx.BlockLabel(inst->Arg(0).Label())); | ||
| 139 | } | ||
| 140 | |||
| 141 | void EmitSPIRV::EmitBranchConditional(EmitContext& ctx, IR::Inst* inst) { | ||
| 142 | ctx.OpBranchConditional(ctx.Def(inst->Arg(0)), ctx.BlockLabel(inst->Arg(1).Label()), | ||
| 143 | ctx.BlockLabel(inst->Arg(2).Label())); | ||
| 144 | } | ||
| 145 | |||
| 146 | void EmitSPIRV::EmitLoopMerge(EmitContext& ctx, IR::Inst* inst) { | ||
| 147 | ctx.OpLoopMerge(ctx.BlockLabel(inst->Arg(0).Label()), ctx.BlockLabel(inst->Arg(1).Label()), | ||
| 148 | spv::LoopControlMask::MaskNone); | ||
| 149 | } | ||
| 150 | |||
| 151 | void EmitSPIRV::EmitSelectionMerge(EmitContext& ctx, IR::Inst* inst) { | ||
| 152 | ctx.OpSelectionMerge(ctx.BlockLabel(inst->Arg(0).Label()), spv::SelectionControlMask::MaskNone); | ||
| 153 | } | ||
| 154 | |||
| 155 | void EmitSPIRV::EmitReturn(EmitContext& ctx) { | ||
| 156 | ctx.OpReturn(); | ||
| 157 | } | ||
| 158 | |||
| 118 | void EmitSPIRV::EmitGetZeroFromOp(EmitContext&) { | 159 | void EmitSPIRV::EmitGetZeroFromOp(EmitContext&) { |
| 119 | throw LogicError("Unreachable instruction"); | 160 | throw LogicError("Unreachable instruction"); |
| 120 | } | 161 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 3f4b68a7d..9aa83b5de 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -124,18 +124,20 @@ private: | |||
| 124 | void EmitInst(EmitContext& ctx, IR::Inst* inst); | 124 | void EmitInst(EmitContext& ctx, IR::Inst* inst); |
| 125 | 125 | ||
| 126 | // Microinstruction emitters | 126 | // Microinstruction emitters |
| 127 | void EmitPhi(EmitContext& ctx); | 127 | Id EmitPhi(EmitContext& ctx, IR::Inst* inst); |
| 128 | void EmitVoid(EmitContext& ctx); | 128 | void EmitVoid(EmitContext& ctx); |
| 129 | void EmitIdentity(EmitContext& ctx); | 129 | void EmitIdentity(EmitContext& ctx); |
| 130 | void EmitBranch(EmitContext& ctx, IR::Inst* inst); | 130 | void EmitBranch(EmitContext& ctx, IR::Inst* inst); |
| 131 | void EmitBranchConditional(EmitContext& ctx, IR::Inst* inst); | 131 | void EmitBranchConditional(EmitContext& ctx, IR::Inst* inst); |
| 132 | void EmitExit(EmitContext& ctx); | 132 | void EmitLoopMerge(EmitContext& ctx, IR::Inst* inst); |
| 133 | void EmitSelectionMerge(EmitContext& ctx, IR::Inst* inst); | ||
| 133 | void EmitReturn(EmitContext& ctx); | 134 | void EmitReturn(EmitContext& ctx); |
| 134 | void EmitUnreachable(EmitContext& ctx); | ||
| 135 | void EmitGetRegister(EmitContext& ctx); | 135 | void EmitGetRegister(EmitContext& ctx); |
| 136 | void EmitSetRegister(EmitContext& ctx); | 136 | void EmitSetRegister(EmitContext& ctx); |
| 137 | void EmitGetPred(EmitContext& ctx); | 137 | void EmitGetPred(EmitContext& ctx); |
| 138 | void EmitSetPred(EmitContext& ctx); | 138 | void EmitSetPred(EmitContext& ctx); |
| 139 | void EmitSetGotoVariable(EmitContext& ctx); | ||
| 140 | void EmitGetGotoVariable(EmitContext& ctx); | ||
| 139 | Id EmitGetCbuf(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | 141 | Id EmitGetCbuf(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); |
| 140 | void EmitGetAttribute(EmitContext& ctx); | 142 | void EmitGetAttribute(EmitContext& ctx); |
| 141 | void EmitSetAttribute(EmitContext& ctx); | 143 | void EmitSetAttribute(EmitContext& ctx); |
| @@ -151,11 +153,11 @@ private: | |||
| 151 | void EmitSetOFlag(EmitContext& ctx); | 153 | void EmitSetOFlag(EmitContext& ctx); |
| 152 | Id EmitWorkgroupId(EmitContext& ctx); | 154 | Id EmitWorkgroupId(EmitContext& ctx); |
| 153 | Id EmitLocalInvocationId(EmitContext& ctx); | 155 | Id EmitLocalInvocationId(EmitContext& ctx); |
| 154 | void EmitUndef1(EmitContext& ctx); | 156 | Id EmitUndefU1(EmitContext& ctx); |
| 155 | void EmitUndef8(EmitContext& ctx); | 157 | void EmitUndefU8(EmitContext& ctx); |
| 156 | void EmitUndef16(EmitContext& ctx); | 158 | void EmitUndefU16(EmitContext& ctx); |
| 157 | void EmitUndef32(EmitContext& ctx); | 159 | void EmitUndefU32(EmitContext& ctx); |
| 158 | void EmitUndef64(EmitContext& ctx); | 160 | void EmitUndefU64(EmitContext& ctx); |
| 159 | void EmitLoadGlobalU8(EmitContext& ctx); | 161 | void EmitLoadGlobalU8(EmitContext& ctx); |
| 160 | void EmitLoadGlobalS8(EmitContext& ctx); | 162 | void EmitLoadGlobalS8(EmitContext& ctx); |
| 161 | void EmitLoadGlobalU16(EmitContext& ctx); | 163 | void EmitLoadGlobalU16(EmitContext& ctx); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index b121305ea..1eab739ed 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -22,6 +22,14 @@ void EmitSPIRV::EmitSetPred(EmitContext&) { | |||
| 22 | throw NotImplementedException("SPIR-V Instruction"); | 22 | throw NotImplementedException("SPIR-V Instruction"); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void EmitSPIRV::EmitSetGotoVariable(EmitContext&) { | ||
| 26 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 27 | } | ||
| 28 | |||
| 29 | void EmitSPIRV::EmitGetGotoVariable(EmitContext&) { | ||
| 30 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 31 | } | ||
| 32 | |||
| 25 | Id EmitSPIRV::EmitGetCbuf(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 33 | Id EmitSPIRV::EmitGetCbuf(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 26 | if (!binding.IsImmediate()) { | 34 | if (!binding.IsImmediate()) { |
| 27 | throw NotImplementedException("Constant buffer indexing"); | 35 | throw NotImplementedException("Constant buffer indexing"); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp index 770fe113c..66ce6c8c5 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp | |||
| @@ -3,28 +3,3 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | |||
| 7 | namespace Shader::Backend::SPIRV { | ||
| 8 | |||
| 9 | void EmitSPIRV::EmitBranch(EmitContext& ctx, IR::Inst* inst) { | ||
| 10 | ctx.OpBranch(ctx.BlockLabel(inst->Arg(0).Label())); | ||
| 11 | } | ||
| 12 | |||
| 13 | void EmitSPIRV::EmitBranchConditional(EmitContext& ctx, IR::Inst* inst) { | ||
| 14 | ctx.OpBranchConditional(ctx.Def(inst->Arg(0)), ctx.BlockLabel(inst->Arg(1).Label()), | ||
| 15 | ctx.BlockLabel(inst->Arg(2).Label())); | ||
| 16 | } | ||
| 17 | |||
| 18 | void EmitSPIRV::EmitExit(EmitContext& ctx) { | ||
| 19 | ctx.OpReturn(); | ||
| 20 | } | ||
| 21 | |||
| 22 | void EmitSPIRV::EmitReturn(EmitContext&) { | ||
| 23 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 24 | } | ||
| 25 | |||
| 26 | void EmitSPIRV::EmitUnreachable(EmitContext&) { | ||
| 27 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 28 | } | ||
| 29 | |||
| 30 | } // namespace Shader::Backend::SPIRV | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp index 3850b072c..859b60a95 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp | |||
| @@ -6,23 +6,23 @@ | |||
| 6 | 6 | ||
| 7 | namespace Shader::Backend::SPIRV { | 7 | namespace Shader::Backend::SPIRV { |
| 8 | 8 | ||
| 9 | void EmitSPIRV::EmitUndef1(EmitContext&) { | 9 | Id EmitSPIRV::EmitUndefU1(EmitContext& ctx) { |
| 10 | throw NotImplementedException("SPIR-V Instruction"); | 10 | return ctx.OpUndef(ctx.u1); |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | void EmitSPIRV::EmitUndef8(EmitContext&) { | 13 | void EmitSPIRV::EmitUndefU8(EmitContext&) { |
| 14 | throw NotImplementedException("SPIR-V Instruction"); | 14 | throw NotImplementedException("SPIR-V Instruction"); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | void EmitSPIRV::EmitUndef16(EmitContext&) { | 17 | void EmitSPIRV::EmitUndefU16(EmitContext&) { |
| 18 | throw NotImplementedException("SPIR-V Instruction"); | 18 | throw NotImplementedException("SPIR-V Instruction"); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | void EmitSPIRV::EmitUndef32(EmitContext&) { | 21 | void EmitSPIRV::EmitUndefU32(EmitContext&) { |
| 22 | throw NotImplementedException("SPIR-V Instruction"); | 22 | throw NotImplementedException("SPIR-V Instruction"); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void EmitSPIRV::EmitUndef64(EmitContext&) { | 25 | void EmitSPIRV::EmitUndefU64(EmitContext&) { |
| 26 | throw NotImplementedException("SPIR-V Instruction"); | 26 | throw NotImplementedException("SPIR-V Instruction"); |
| 27 | } | 27 | } |
| 28 | 28 | ||