spirv: Initial SPIR-V support
This commit is contained in:
		
							
								
								
									
										2
									
								
								externals/sirit
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								externals/sirit
									
									
									
									
										vendored
									
									
								
							 Submodule externals/sirit updated: eefca56afd...1f7b70730d
									
								
							| @@ -1,5 +1,16 @@ | ||||
| add_executable(shader_recompiler | ||||
|     backend/spirv/emit_spirv.cpp | ||||
|     backend/spirv/emit_spirv.h | ||||
|     backend/spirv/emit_spirv_bitwise_conversion.cpp | ||||
|     backend/spirv/emit_spirv_composite.cpp | ||||
|     backend/spirv/emit_spirv_context_get_set.cpp | ||||
|     backend/spirv/emit_spirv_control_flow.cpp | ||||
|     backend/spirv/emit_spirv_floating_point.cpp | ||||
|     backend/spirv/emit_spirv_integer.cpp | ||||
|     backend/spirv/emit_spirv_logical.cpp | ||||
|     backend/spirv/emit_spirv_memory.cpp | ||||
|     backend/spirv/emit_spirv_select.cpp | ||||
|     backend/spirv/emit_spirv_undefined.cpp | ||||
|     environment.h | ||||
|     exception.h | ||||
|     file_environment.cpp | ||||
| @@ -72,7 +83,9 @@ add_executable(shader_recompiler | ||||
|     main.cpp | ||||
|     object_pool.h | ||||
| ) | ||||
| target_link_libraries(shader_recompiler PRIVATE fmt::fmt) | ||||
|  | ||||
| target_include_directories(video_core PRIVATE sirit) | ||||
| target_link_libraries(shader_recompiler PRIVATE fmt::fmt sirit) | ||||
|  | ||||
| if (MSVC) | ||||
|     target_compile_options(shader_recompiler PRIVATE | ||||
|   | ||||
							
								
								
									
										134
									
								
								src/shader_recompiler/backend/spirv/emit_spirv.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								src/shader_recompiler/backend/spirv/emit_spirv.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include <numeric> | ||||
| #include <type_traits> | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
| #include "shader_recompiler/frontend/ir/basic_block.h" | ||||
| #include "shader_recompiler/frontend/ir/function.h" | ||||
| #include "shader_recompiler/frontend/ir/microinstruction.h" | ||||
| #include "shader_recompiler/frontend/ir/program.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| EmitContext::EmitContext(IR::Program& program) { | ||||
|     AddCapability(spv::Capability::Shader); | ||||
|     AddCapability(spv::Capability::Float16); | ||||
|     AddCapability(spv::Capability::Float64); | ||||
|     void_id = TypeVoid(); | ||||
|  | ||||
|     u1 = Name(TypeBool(), "u1"); | ||||
|     f32.Define(*this, TypeFloat(32), "f32"); | ||||
|     u32.Define(*this, TypeInt(32, false), "u32"); | ||||
|     f16.Define(*this, TypeFloat(16), "f16"); | ||||
|     f64.Define(*this, TypeFloat(64), "f64"); | ||||
|  | ||||
|     for (const IR::Function& function : program.functions) { | ||||
|         for (IR::Block* const block : function.blocks) { | ||||
|             block_label_map.emplace_back(block, OpLabel()); | ||||
|         } | ||||
|     } | ||||
|     std::ranges::sort(block_label_map, {}, &std::pair<IR::Block*, Id>::first); | ||||
| } | ||||
|  | ||||
| EmitContext::~EmitContext() = default; | ||||
|  | ||||
| EmitSPIRV::EmitSPIRV(IR::Program& program) { | ||||
|     EmitContext ctx{program}; | ||||
|     const Id void_function{ctx.TypeFunction(ctx.void_id)}; | ||||
|     // FIXME: Forward declare functions (needs sirit support) | ||||
|     Id func{}; | ||||
|     for (IR::Function& function : program.functions) { | ||||
|         func = ctx.OpFunction(ctx.void_id, spv::FunctionControlMask::MaskNone, void_function); | ||||
|         for (IR::Block* const block : function.blocks) { | ||||
|             ctx.AddLabel(ctx.BlockLabel(block)); | ||||
|             for (IR::Inst& inst : block->Instructions()) { | ||||
|                 EmitInst(ctx, &inst); | ||||
|             } | ||||
|         } | ||||
|         ctx.OpFunctionEnd(); | ||||
|     } | ||||
|     ctx.AddEntryPoint(spv::ExecutionModel::GLCompute, func, "main"); | ||||
|  | ||||
|     std::vector<u32> result{ctx.Assemble()}; | ||||
|     std::FILE* file{std::fopen("shader.spv", "wb")}; | ||||
|     std::fwrite(result.data(), sizeof(u32), result.size(), file); | ||||
|     std::fclose(file); | ||||
|     std::system("spirv-dis shader.spv"); | ||||
|     std::system("spirv-val shader.spv"); | ||||
| } | ||||
|  | ||||
| template <auto method> | ||||
| static void Invoke(EmitSPIRV& emit, EmitContext& ctx, IR::Inst* inst) { | ||||
|     using M = decltype(method); | ||||
|     using std::is_invocable_r_v; | ||||
|     if constexpr (is_invocable_r_v<Id, M, EmitSPIRV&, EmitContext&>) { | ||||
|         ctx.Define(inst, (emit.*method)(ctx)); | ||||
|     } else if constexpr (is_invocable_r_v<Id, M, EmitSPIRV&, EmitContext&, Id>) { | ||||
|         ctx.Define(inst, (emit.*method)(ctx, ctx.Def(inst->Arg(0)))); | ||||
|     } else if constexpr (is_invocable_r_v<Id, M, EmitSPIRV&, EmitContext&, Id, Id>) { | ||||
|         ctx.Define(inst, (emit.*method)(ctx, ctx.Def(inst->Arg(0)), ctx.Def(inst->Arg(1)))); | ||||
|     } else if constexpr (is_invocable_r_v<Id, M, EmitSPIRV&, EmitContext&, Id, Id, Id>) { | ||||
|         ctx.Define(inst, (emit.*method)(ctx, ctx.Def(inst->Arg(0)), ctx.Def(inst->Arg(1)), | ||||
|                                         ctx.Def(inst->Arg(2)))); | ||||
|     } else if constexpr (is_invocable_r_v<Id, M, EmitSPIRV&, EmitContext&, IR::Inst*, Id, Id>) { | ||||
|         ctx.Define(inst, (emit.*method)(ctx, inst, ctx.Def(inst->Arg(0)), ctx.Def(inst->Arg(1)))); | ||||
|     } else if constexpr (is_invocable_r_v<Id, M, EmitSPIRV&, EmitContext&, IR::Inst*, Id, Id, Id>) { | ||||
|         ctx.Define(inst, (emit.*method)(ctx, inst, ctx.Def(inst->Arg(0)), ctx.Def(inst->Arg(1)), | ||||
|                                         ctx.Def(inst->Arg(2)))); | ||||
|     } else if constexpr (is_invocable_r_v<Id, M, EmitSPIRV&, EmitContext&, Id, u32>) { | ||||
|         ctx.Define(inst, (emit.*method)(ctx, ctx.Def(inst->Arg(0)), inst->Arg(1).U32())); | ||||
|     } else if constexpr (is_invocable_r_v<Id, M, EmitSPIRV&, EmitContext&, const IR::Value&>) { | ||||
|         ctx.Define(inst, (emit.*method)(ctx, inst->Arg(0))); | ||||
|     } else if constexpr (is_invocable_r_v<Id, M, EmitSPIRV&, EmitContext&, const IR::Value&, | ||||
|                                           const IR::Value&>) { | ||||
|         ctx.Define(inst, (emit.*method)(ctx, inst->Arg(0), inst->Arg(1))); | ||||
|     } else if constexpr (is_invocable_r_v<void, M, EmitSPIRV&, EmitContext&, IR::Inst*>) { | ||||
|         (emit.*method)(ctx, inst); | ||||
|     } else if constexpr (is_invocable_r_v<void, M, EmitSPIRV&, EmitContext&>) { | ||||
|         (emit.*method)(ctx); | ||||
|     } else { | ||||
|         static_assert(false, "Bad format"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitInst(EmitContext& ctx, IR::Inst* inst) { | ||||
|     switch (inst->Opcode()) { | ||||
| #define OPCODE(name, result_type, ...)                                                             \ | ||||
|     case IR::Opcode::name:                                                                         \ | ||||
|         return Invoke<&EmitSPIRV::Emit##name>(*this, ctx, inst); | ||||
| #include "shader_recompiler/frontend/ir/opcodes.inc" | ||||
| #undef OPCODE | ||||
|     } | ||||
|     throw LogicError("Invalid opcode {}", inst->Opcode()); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitPhi(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitVoid(EmitContext&) {} | ||||
|  | ||||
| void EmitSPIRV::EmitIdentity(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetZeroFromOp(EmitContext&) { | ||||
|     throw LogicError("Unreachable instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetSignFromOp(EmitContext&) { | ||||
|     throw LogicError("Unreachable instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetCarryFromOp(EmitContext&) { | ||||
|     throw LogicError("Unreachable instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetOverflowFromOp(EmitContext&) { | ||||
|     throw LogicError("Unreachable instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
| @@ -4,18 +4,326 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <sirit/sirit.h> | ||||
|  | ||||
| #include <boost/container/flat_map.hpp> | ||||
|  | ||||
| #include "common/common_types.h" | ||||
| #include "shader_recompiler/frontend/ir/microinstruction.h" | ||||
| #include "shader_recompiler/frontend/ir/program.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| using Sirit::Id; | ||||
|  | ||||
| class DefMap { | ||||
| public: | ||||
|     void Define(IR::Inst* inst, Id def_id) { | ||||
|         const InstInfo info{.use_count{inst->UseCount()}, .def_id{def_id}}; | ||||
|         const auto it{map.insert(map.end(), std::make_pair(inst, info))}; | ||||
|         if (it == map.end()) { | ||||
|             throw LogicError("Defining already defined instruction"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] Id Consume(IR::Inst* inst) { | ||||
|         const auto it{map.find(inst)}; | ||||
|         if (it == map.end()) { | ||||
|             throw LogicError("Consuming undefined instruction"); | ||||
|         } | ||||
|         const Id def_id{it->second.def_id}; | ||||
|         if (--it->second.use_count == 0) { | ||||
|             map.erase(it); | ||||
|         } | ||||
|         return def_id; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     struct InstInfo { | ||||
|         int use_count; | ||||
|         Id def_id; | ||||
|     }; | ||||
|  | ||||
|     boost::container::flat_map<IR::Inst*, InstInfo> map; | ||||
| }; | ||||
|  | ||||
| class VectorTypes { | ||||
| public: | ||||
|     void Define(Sirit::Module& sirit_ctx, Id base_type, std::string_view name) { | ||||
|         defs[0] = sirit_ctx.Name(base_type, name); | ||||
|  | ||||
|         std::array<char, 6> def_name; | ||||
|         for (int i = 1; i < 4; ++i) { | ||||
|             const std::string_view def_name_view( | ||||
|                 def_name.data(), | ||||
|                 fmt::format_to_n(def_name.data(), def_name.size(), "{}x{}", name, i + 1).size); | ||||
|             defs[i] = sirit_ctx.Name(sirit_ctx.TypeVector(base_type, i + 1), def_name_view); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] Id operator[](size_t size) const noexcept { | ||||
|         return defs[size - 1]; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     std::array<Id, 4> defs; | ||||
| }; | ||||
|  | ||||
| class EmitContext final : public Sirit::Module { | ||||
| public: | ||||
|     explicit EmitContext(IR::Program& program); | ||||
|     ~EmitContext(); | ||||
|  | ||||
|     [[nodiscard]] Id Def(const IR::Value& value) { | ||||
|         if (!value.IsImmediate()) { | ||||
|             return def_map.Consume(value.Inst()); | ||||
|         } | ||||
|         switch (value.Type()) { | ||||
|         case IR::Type::U32: | ||||
|             return Constant(u32[1], value.U32()); | ||||
|         case IR::Type::F32: | ||||
|             return Constant(f32[1], value.F32()); | ||||
|         default: | ||||
|             throw NotImplementedException("Immediate type {}", value.Type()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void Define(IR::Inst* inst, Id def_id) { | ||||
|         def_map.Define(inst, def_id); | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] Id BlockLabel(IR::Block* block) const { | ||||
|         const auto it{std::ranges::lower_bound(block_label_map, block, {}, | ||||
|                                                &std::pair<IR::Block*, Id>::first)}; | ||||
|         if (it == block_label_map.end()) { | ||||
|             throw LogicError("Undefined block"); | ||||
|         } | ||||
|         return it->second; | ||||
|     } | ||||
|  | ||||
|     Id void_id{}; | ||||
|     Id u1{}; | ||||
|     VectorTypes f32; | ||||
|     VectorTypes u32; | ||||
|     VectorTypes f16; | ||||
|     VectorTypes f64; | ||||
|  | ||||
|     Id workgroup_id{}; | ||||
|     Id local_invocation_id{}; | ||||
|  | ||||
| private: | ||||
|     DefMap def_map; | ||||
|     std::vector<std::pair<IR::Block*, Id>> block_label_map; | ||||
| }; | ||||
|  | ||||
| class EmitSPIRV { | ||||
| public: | ||||
|     explicit EmitSPIRV(IR::Program& program); | ||||
|  | ||||
| private: | ||||
|     void EmitInst(EmitContext& ctx, IR::Inst* inst); | ||||
|  | ||||
|     // Microinstruction emitters | ||||
| #define OPCODE(name, result_type, ...) void Emit##name(EmitContext& ctx, IR::Inst* inst); | ||||
| #include "shader_recompiler/frontend/ir/opcodes.inc" | ||||
| #undef OPCODE | ||||
|     void EmitPhi(EmitContext& ctx); | ||||
|     void EmitVoid(EmitContext& ctx); | ||||
|     void EmitIdentity(EmitContext& ctx); | ||||
|     void EmitBranch(EmitContext& ctx, IR::Inst* inst); | ||||
|     void EmitBranchConditional(EmitContext& ctx, IR::Inst* inst); | ||||
|     void EmitExit(EmitContext& ctx); | ||||
|     void EmitReturn(EmitContext& ctx); | ||||
|     void EmitUnreachable(EmitContext& ctx); | ||||
|     void EmitGetRegister(EmitContext& ctx); | ||||
|     void EmitSetRegister(EmitContext& ctx); | ||||
|     void EmitGetPred(EmitContext& ctx); | ||||
|     void EmitSetPred(EmitContext& ctx); | ||||
|     Id EmitGetCbuf(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | ||||
|     void EmitGetAttribute(EmitContext& ctx); | ||||
|     void EmitSetAttribute(EmitContext& ctx); | ||||
|     void EmitGetAttributeIndexed(EmitContext& ctx); | ||||
|     void EmitSetAttributeIndexed(EmitContext& ctx); | ||||
|     void EmitGetZFlag(EmitContext& ctx); | ||||
|     void EmitGetSFlag(EmitContext& ctx); | ||||
|     void EmitGetCFlag(EmitContext& ctx); | ||||
|     void EmitGetOFlag(EmitContext& ctx); | ||||
|     void EmitSetZFlag(EmitContext& ctx); | ||||
|     void EmitSetSFlag(EmitContext& ctx); | ||||
|     void EmitSetCFlag(EmitContext& ctx); | ||||
|     void EmitSetOFlag(EmitContext& ctx); | ||||
|     Id EmitWorkgroupId(EmitContext& ctx); | ||||
|     Id EmitLocalInvocationId(EmitContext& ctx); | ||||
|     void EmitUndef1(EmitContext& ctx); | ||||
|     void EmitUndef8(EmitContext& ctx); | ||||
|     void EmitUndef16(EmitContext& ctx); | ||||
|     void EmitUndef32(EmitContext& ctx); | ||||
|     void EmitUndef64(EmitContext& ctx); | ||||
|     void EmitLoadGlobalU8(EmitContext& ctx); | ||||
|     void EmitLoadGlobalS8(EmitContext& ctx); | ||||
|     void EmitLoadGlobalU16(EmitContext& ctx); | ||||
|     void EmitLoadGlobalS16(EmitContext& ctx); | ||||
|     void EmitLoadGlobal32(EmitContext& ctx); | ||||
|     void EmitLoadGlobal64(EmitContext& ctx); | ||||
|     void EmitLoadGlobal128(EmitContext& ctx); | ||||
|     void EmitWriteGlobalU8(EmitContext& ctx); | ||||
|     void EmitWriteGlobalS8(EmitContext& ctx); | ||||
|     void EmitWriteGlobalU16(EmitContext& ctx); | ||||
|     void EmitWriteGlobalS16(EmitContext& ctx); | ||||
|     void EmitWriteGlobal32(EmitContext& ctx); | ||||
|     void EmitWriteGlobal64(EmitContext& ctx); | ||||
|     void EmitWriteGlobal128(EmitContext& ctx); | ||||
|     void EmitLoadStorageU8(EmitContext& ctx); | ||||
|     void EmitLoadStorageS8(EmitContext& ctx); | ||||
|     void EmitLoadStorageU16(EmitContext& ctx); | ||||
|     void EmitLoadStorageS16(EmitContext& ctx); | ||||
|     Id EmitLoadStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | ||||
|     void EmitLoadStorage64(EmitContext& ctx); | ||||
|     void EmitLoadStorage128(EmitContext& ctx); | ||||
|     void EmitWriteStorageU8(EmitContext& ctx); | ||||
|     void EmitWriteStorageS8(EmitContext& ctx); | ||||
|     void EmitWriteStorageU16(EmitContext& ctx); | ||||
|     void EmitWriteStorageS16(EmitContext& ctx); | ||||
|     void EmitWriteStorage32(EmitContext& ctx); | ||||
|     void EmitWriteStorage64(EmitContext& ctx); | ||||
|     void EmitWriteStorage128(EmitContext& ctx); | ||||
|     void EmitCompositeConstructU32x2(EmitContext& ctx); | ||||
|     void EmitCompositeConstructU32x3(EmitContext& ctx); | ||||
|     void EmitCompositeConstructU32x4(EmitContext& ctx); | ||||
|     void EmitCompositeExtractU32x2(EmitContext& ctx); | ||||
|     Id EmitCompositeExtractU32x3(EmitContext& ctx, Id vector, u32 index); | ||||
|     void EmitCompositeExtractU32x4(EmitContext& ctx); | ||||
|     void EmitCompositeConstructF16x2(EmitContext& ctx); | ||||
|     void EmitCompositeConstructF16x3(EmitContext& ctx); | ||||
|     void EmitCompositeConstructF16x4(EmitContext& ctx); | ||||
|     void EmitCompositeExtractF16x2(EmitContext& ctx); | ||||
|     void EmitCompositeExtractF16x3(EmitContext& ctx); | ||||
|     void EmitCompositeExtractF16x4(EmitContext& ctx); | ||||
|     void EmitCompositeConstructF32x2(EmitContext& ctx); | ||||
|     void EmitCompositeConstructF32x3(EmitContext& ctx); | ||||
|     void EmitCompositeConstructF32x4(EmitContext& ctx); | ||||
|     void EmitCompositeExtractF32x2(EmitContext& ctx); | ||||
|     void EmitCompositeExtractF32x3(EmitContext& ctx); | ||||
|     void EmitCompositeExtractF32x4(EmitContext& ctx); | ||||
|     void EmitCompositeConstructF64x2(EmitContext& ctx); | ||||
|     void EmitCompositeConstructF64x3(EmitContext& ctx); | ||||
|     void EmitCompositeConstructF64x4(EmitContext& ctx); | ||||
|     void EmitCompositeExtractF64x2(EmitContext& ctx); | ||||
|     void EmitCompositeExtractF64x3(EmitContext& ctx); | ||||
|     void EmitCompositeExtractF64x4(EmitContext& ctx); | ||||
|     void EmitSelect8(EmitContext& ctx); | ||||
|     void EmitSelect16(EmitContext& ctx); | ||||
|     void EmitSelect32(EmitContext& ctx); | ||||
|     void EmitSelect64(EmitContext& ctx); | ||||
|     void EmitBitCastU16F16(EmitContext& ctx); | ||||
|     Id EmitBitCastU32F32(EmitContext& ctx, Id value); | ||||
|     void EmitBitCastU64F64(EmitContext& ctx); | ||||
|     void EmitBitCastF16U16(EmitContext& ctx); | ||||
|     Id EmitBitCastF32U32(EmitContext& ctx, Id value); | ||||
|     void EmitBitCastF64U64(EmitContext& ctx); | ||||
|     void EmitPackUint2x32(EmitContext& ctx); | ||||
|     void EmitUnpackUint2x32(EmitContext& ctx); | ||||
|     void EmitPackFloat2x16(EmitContext& ctx); | ||||
|     void EmitUnpackFloat2x16(EmitContext& ctx); | ||||
|     void EmitPackDouble2x32(EmitContext& ctx); | ||||
|     void EmitUnpackDouble2x32(EmitContext& ctx); | ||||
|     void EmitGetZeroFromOp(EmitContext& ctx); | ||||
|     void EmitGetSignFromOp(EmitContext& ctx); | ||||
|     void EmitGetCarryFromOp(EmitContext& ctx); | ||||
|     void EmitGetOverflowFromOp(EmitContext& ctx); | ||||
|     void EmitFPAbs16(EmitContext& ctx); | ||||
|     void EmitFPAbs32(EmitContext& ctx); | ||||
|     void EmitFPAbs64(EmitContext& ctx); | ||||
|     Id EmitFPAdd16(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
|     Id EmitFPAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
|     Id EmitFPAdd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
|     Id EmitFPFma16(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c); | ||||
|     Id EmitFPFma32(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c); | ||||
|     Id EmitFPFma64(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c); | ||||
|     void EmitFPMax32(EmitContext& ctx); | ||||
|     void EmitFPMax64(EmitContext& ctx); | ||||
|     void EmitFPMin32(EmitContext& ctx); | ||||
|     void EmitFPMin64(EmitContext& ctx); | ||||
|     Id EmitFPMul16(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
|     Id EmitFPMul32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
|     Id EmitFPMul64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
|     void EmitFPNeg16(EmitContext& ctx); | ||||
|     void EmitFPNeg32(EmitContext& ctx); | ||||
|     void EmitFPNeg64(EmitContext& ctx); | ||||
|     void EmitFPRecip32(EmitContext& ctx); | ||||
|     void EmitFPRecip64(EmitContext& ctx); | ||||
|     void EmitFPRecipSqrt32(EmitContext& ctx); | ||||
|     void EmitFPRecipSqrt64(EmitContext& ctx); | ||||
|     void EmitFPSqrt(EmitContext& ctx); | ||||
|     void EmitFPSin(EmitContext& ctx); | ||||
|     void EmitFPSinNotReduced(EmitContext& ctx); | ||||
|     void EmitFPExp2(EmitContext& ctx); | ||||
|     void EmitFPExp2NotReduced(EmitContext& ctx); | ||||
|     void EmitFPCos(EmitContext& ctx); | ||||
|     void EmitFPCosNotReduced(EmitContext& ctx); | ||||
|     void EmitFPLog2(EmitContext& ctx); | ||||
|     void EmitFPSaturate16(EmitContext& ctx); | ||||
|     void EmitFPSaturate32(EmitContext& ctx); | ||||
|     void EmitFPSaturate64(EmitContext& ctx); | ||||
|     void EmitFPRoundEven16(EmitContext& ctx); | ||||
|     void EmitFPRoundEven32(EmitContext& ctx); | ||||
|     void EmitFPRoundEven64(EmitContext& ctx); | ||||
|     void EmitFPFloor16(EmitContext& ctx); | ||||
|     void EmitFPFloor32(EmitContext& ctx); | ||||
|     void EmitFPFloor64(EmitContext& ctx); | ||||
|     void EmitFPCeil16(EmitContext& ctx); | ||||
|     void EmitFPCeil32(EmitContext& ctx); | ||||
|     void EmitFPCeil64(EmitContext& ctx); | ||||
|     void EmitFPTrunc16(EmitContext& ctx); | ||||
|     void EmitFPTrunc32(EmitContext& ctx); | ||||
|     void EmitFPTrunc64(EmitContext& ctx); | ||||
|     Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
|     void EmitIAdd64(EmitContext& ctx); | ||||
|     Id EmitISub32(EmitContext& ctx, Id a, Id b); | ||||
|     void EmitISub64(EmitContext& ctx); | ||||
|     Id EmitIMul32(EmitContext& ctx, Id a, Id b); | ||||
|     void EmitINeg32(EmitContext& ctx); | ||||
|     void EmitIAbs32(EmitContext& ctx); | ||||
|     Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift); | ||||
|     void EmitShiftRightLogical32(EmitContext& ctx); | ||||
|     void EmitShiftRightArithmetic32(EmitContext& ctx); | ||||
|     void EmitBitwiseAnd32(EmitContext& ctx); | ||||
|     void EmitBitwiseOr32(EmitContext& ctx); | ||||
|     void EmitBitwiseXor32(EmitContext& ctx); | ||||
|     void EmitBitFieldInsert(EmitContext& ctx); | ||||
|     void EmitBitFieldSExtract(EmitContext& ctx); | ||||
|     Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); | ||||
|     void EmitSLessThan(EmitContext& ctx); | ||||
|     void EmitULessThan(EmitContext& ctx); | ||||
|     void EmitIEqual(EmitContext& ctx); | ||||
|     void EmitSLessThanEqual(EmitContext& ctx); | ||||
|     void EmitULessThanEqual(EmitContext& ctx); | ||||
|     void EmitSGreaterThan(EmitContext& ctx); | ||||
|     void EmitUGreaterThan(EmitContext& ctx); | ||||
|     void EmitINotEqual(EmitContext& ctx); | ||||
|     void EmitSGreaterThanEqual(EmitContext& ctx); | ||||
|     Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs); | ||||
|     void EmitLogicalOr(EmitContext& ctx); | ||||
|     void EmitLogicalAnd(EmitContext& ctx); | ||||
|     void EmitLogicalXor(EmitContext& ctx); | ||||
|     void EmitLogicalNot(EmitContext& ctx); | ||||
|     void EmitConvertS16F16(EmitContext& ctx); | ||||
|     void EmitConvertS16F32(EmitContext& ctx); | ||||
|     void EmitConvertS16F64(EmitContext& ctx); | ||||
|     void EmitConvertS32F16(EmitContext& ctx); | ||||
|     void EmitConvertS32F32(EmitContext& ctx); | ||||
|     void EmitConvertS32F64(EmitContext& ctx); | ||||
|     void EmitConvertS64F16(EmitContext& ctx); | ||||
|     void EmitConvertS64F32(EmitContext& ctx); | ||||
|     void EmitConvertS64F64(EmitContext& ctx); | ||||
|     void EmitConvertU16F16(EmitContext& ctx); | ||||
|     void EmitConvertU16F32(EmitContext& ctx); | ||||
|     void EmitConvertU16F64(EmitContext& ctx); | ||||
|     void EmitConvertU32F16(EmitContext& ctx); | ||||
|     void EmitConvertU32F32(EmitContext& ctx); | ||||
|     void EmitConvertU32F64(EmitContext& ctx); | ||||
|     void EmitConvertU64F16(EmitContext& ctx); | ||||
|     void EmitConvertU64F32(EmitContext& ctx); | ||||
|     void EmitConvertU64F64(EmitContext& ctx); | ||||
|     void EmitConvertU64U32(EmitContext& ctx); | ||||
|     void EmitConvertU32U64(EmitContext& ctx); | ||||
| }; | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
|   | ||||
| @@ -0,0 +1,57 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitSPIRV::EmitBitCastU16F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitBitCastU32F32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpBitcast(ctx.u32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitBitCastU64F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitBitCastF16U16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitBitCastF32U32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpBitcast(ctx.f32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitBitCastF64U64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitPackUint2x32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitUnpackUint2x32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitPackFloat2x16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitUnpackFloat2x16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitPackDouble2x32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitUnpackDouble2x32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
							
								
								
									
										105
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructU32x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructU32x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructU32x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractU32x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitCompositeExtractU32x3(EmitContext& ctx, Id vector, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.u32[1], vector, index); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractU32x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructF16x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructF16x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructF16x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractF16x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractF16x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractF16x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructF32x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructF32x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructF32x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractF32x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractF32x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractF32x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructF64x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructF64x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeConstructF64x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractF64x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractF64x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitCompositeExtractF64x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
| @@ -0,0 +1,102 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitSPIRV::EmitGetRegister(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSetRegister(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetPred(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSetPred(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitGetCbuf(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | ||||
|     if (!binding.IsImmediate()) { | ||||
|         throw NotImplementedException("Constant buffer indexing"); | ||||
|     } | ||||
|     if (!offset.IsImmediate()) { | ||||
|         throw NotImplementedException("Variable constant buffer offset"); | ||||
|     } | ||||
|     return ctx.Name(ctx.OpUndef(ctx.u32[1]), "unimplemented_cbuf"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetAttribute(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSetAttribute(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetAttributeIndexed(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSetAttributeIndexed(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetZFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetSFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetCFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitGetOFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSetZFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSetSFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSetCFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSetOFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitWorkgroupId(EmitContext& ctx) { | ||||
|     if (ctx.workgroup_id.value == 0) { | ||||
|         ctx.workgroup_id = ctx.AddGlobalVariable( | ||||
|             ctx.TypePointer(spv::StorageClass::Input, ctx.u32[3]), spv::StorageClass::Input); | ||||
|         ctx.Decorate(ctx.workgroup_id, spv::Decoration::BuiltIn, spv::BuiltIn::WorkgroupId); | ||||
|     } | ||||
|     return ctx.OpLoad(ctx.u32[3], ctx.workgroup_id); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitLocalInvocationId(EmitContext& ctx) { | ||||
|     if (ctx.local_invocation_id.value == 0) { | ||||
|         ctx.local_invocation_id = ctx.AddGlobalVariable( | ||||
|             ctx.TypePointer(spv::StorageClass::Input, ctx.u32[3]), spv::StorageClass::Input); | ||||
|         ctx.Decorate(ctx.local_invocation_id, spv::Decoration::BuiltIn, | ||||
|                      spv::BuiltIn::LocalInvocationId); | ||||
|     } | ||||
|     return ctx.OpLoad(ctx.u32[3], ctx.local_invocation_id); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
| @@ -0,0 +1,30 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitSPIRV::EmitBranch(EmitContext& ctx, IR::Inst* inst) { | ||||
|     ctx.OpBranch(ctx.BlockLabel(inst->Arg(0).Label())); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitBranchConditional(EmitContext& ctx, IR::Inst* inst) { | ||||
|     ctx.OpBranchConditional(ctx.Def(inst->Arg(0)), ctx.BlockLabel(inst->Arg(1).Label()), | ||||
|                             ctx.BlockLabel(inst->Arg(2).Label())); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitExit(EmitContext& ctx) { | ||||
|     ctx.OpReturn(); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitReturn(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitUnreachable(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
| @@ -0,0 +1,220 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
| #include "shader_recompiler/frontend/ir/modifiers.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
| namespace { | ||||
| Id Decorate(EmitContext& ctx, IR::Inst* inst, Id op) { | ||||
|     const auto flags{inst->Flags<IR::FpControl>()}; | ||||
|     if (flags.no_contraction) { | ||||
|         ctx.Decorate(op, spv::Decoration::NoContraction); | ||||
|     } | ||||
|     switch (flags.rounding) { | ||||
|     case IR::FpRounding::RN: | ||||
|         break; | ||||
|     case IR::FpRounding::RM: | ||||
|         ctx.Decorate(op, spv::Decoration::FPRoundingMode, spv::FPRoundingMode::RTN); | ||||
|         break; | ||||
|     case IR::FpRounding::RP: | ||||
|         ctx.Decorate(op, spv::Decoration::FPRoundingMode, spv::FPRoundingMode::RTP); | ||||
|         break; | ||||
|     case IR::FpRounding::RZ: | ||||
|         ctx.Decorate(op, spv::Decoration::FPRoundingMode, spv::FPRoundingMode::RTZ); | ||||
|         break; | ||||
|     } | ||||
|     if (flags.fmz_mode != IR::FmzMode::FTZ) { | ||||
|         throw NotImplementedException("Denorm management not implemented"); | ||||
|     } | ||||
|     return op; | ||||
| } | ||||
|  | ||||
| } // Anonymous namespace | ||||
|  | ||||
| void EmitSPIRV::EmitFPAbs16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPAbs32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPAbs64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitFPAdd16(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | ||||
|     return Decorate(ctx, inst, ctx.OpFAdd(ctx.f16[1], a, b)); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitFPAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | ||||
|     return Decorate(ctx, inst, ctx.OpFAdd(ctx.f32[1], a, b)); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitFPAdd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | ||||
|     return Decorate(ctx, inst, ctx.OpFAdd(ctx.f64[1], a, b)); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitFPFma16(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c) { | ||||
|     return Decorate(ctx, inst, ctx.OpFma(ctx.f16[1], a, b, c)); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitFPFma32(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c) { | ||||
|     return Decorate(ctx, inst, ctx.OpFma(ctx.f32[1], a, b, c)); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitFPFma64(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c) { | ||||
|     return Decorate(ctx, inst, ctx.OpFma(ctx.f64[1], a, b, c)); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPMax32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPMax64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPMin32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPMin64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitFPMul16(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | ||||
|     return Decorate(ctx, inst, ctx.OpFMul(ctx.f16[1], a, b)); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitFPMul32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | ||||
|     return Decorate(ctx, inst, ctx.OpFMul(ctx.f32[1], a, b)); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitFPMul64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | ||||
|     return Decorate(ctx, inst, ctx.OpFMul(ctx.f64[1], a, b)); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPNeg16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPNeg32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPNeg64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPRecip32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPRecip64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPRecipSqrt32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPRecipSqrt64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPSqrt(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPSin(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPSinNotReduced(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPExp2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPExp2NotReduced(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPCos(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPCosNotReduced(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPLog2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPSaturate16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPSaturate32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPSaturate64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPRoundEven16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPRoundEven32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPRoundEven64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPFloor16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPFloor32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPFloor64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPCeil16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPCeil32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPCeil64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPTrunc16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPTrunc32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitFPTrunc64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
							
								
								
									
										132
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| Id EmitSPIRV::EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | ||||
|     if (inst->HasAssociatedPseudoOperation()) { | ||||
|         throw NotImplementedException("Pseudo-operations on IAdd32"); | ||||
|     } | ||||
|     return ctx.OpIAdd(ctx.u32[1], a, b); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitIAdd64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitISub32(EmitContext& ctx, Id a, Id b) { | ||||
|     return ctx.OpISub(ctx.u32[1], a, b); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitISub64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitIMul32(EmitContext& ctx, Id a, Id b) { | ||||
|     return ctx.OpIMul(ctx.u32[1], a, b); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitINeg32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitIAbs32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift) { | ||||
|     return ctx.OpShiftLeftLogical(ctx.u32[1], base, shift); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitShiftRightLogical32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitShiftRightArithmetic32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitBitwiseAnd32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitBitwiseOr32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitBitwiseXor32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitBitFieldInsert(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitBitFieldSExtract(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count) { | ||||
|     return ctx.OpBitFieldUExtract(ctx.u32[1], base, offset, count); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSLessThan(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitULessThan(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitIEqual(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSLessThanEqual(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitULessThanEqual(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSGreaterThan(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitUGreaterThan(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitINotEqual(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSGreaterThanEqual(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs) { | ||||
|     return ctx.OpUGreaterThanEqual(ctx.u1, lhs, rhs); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLogicalOr(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLogicalAnd(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLogicalXor(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLogicalNot(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
							
								
								
									
										89
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitSPIRV::EmitConvertS16F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertS16F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertS16F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertS32F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertS32F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertS32F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertS64F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertS64F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertS64F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU16F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU16F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU16F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU32F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU32F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU32F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU64F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU64F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU64F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU64U32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitConvertU32U64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
							
								
								
									
										125
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitSPIRV::EmitLoadGlobalU8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadGlobalS8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadGlobalU16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadGlobalS16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadGlobal32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadGlobal64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadGlobal128(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteGlobalU8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteGlobalS8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteGlobalU16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteGlobalS16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteGlobal32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteGlobal64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteGlobal128(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadStorageU8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadStorageS8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadStorageU16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadStorageS16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitSPIRV::EmitLoadStorage32(EmitContext& ctx, const IR::Value& binding, | ||||
|                                 [[maybe_unused]] const IR::Value& offset) { | ||||
|     if (!binding.IsImmediate()) { | ||||
|         throw NotImplementedException("Storage buffer indexing"); | ||||
|     } | ||||
|     return ctx.Name(ctx.OpUndef(ctx.u32[1]), "unimplemented_sbuf"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadStorage64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitLoadStorage128(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteStorageU8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteStorageS8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteStorageU16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteStorageS16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteStorage32(EmitContext& ctx) { | ||||
|     ctx.Name(ctx.OpUndef(ctx.u32[1]), "unimplemented_sbuf_store"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteStorage64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitWriteStorage128(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
							
								
								
									
										25
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_select.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_select.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitSPIRV::EmitSelect8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSelect16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSelect32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitSelect64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
							
								
								
									
										29
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitSPIRV::EmitUndef1(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitUndef8(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitUndef16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitUndef32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSPIRV::EmitUndef64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
| @@ -130,27 +130,27 @@ void IREmitter::SetAttribute(IR::Attribute attribute, const F32& value) { | ||||
| } | ||||
|  | ||||
| U32 IREmitter::WorkgroupIdX() { | ||||
|     return Inst<U32>(Opcode::WorkgroupIdX); | ||||
|     return U32{CompositeExtract(Inst(Opcode::WorkgroupId), 0)}; | ||||
| } | ||||
|  | ||||
| U32 IREmitter::WorkgroupIdY() { | ||||
|     return Inst<U32>(Opcode::WorkgroupIdY); | ||||
|     return U32{CompositeExtract(Inst(Opcode::WorkgroupId), 1)}; | ||||
| } | ||||
|  | ||||
| U32 IREmitter::WorkgroupIdZ() { | ||||
|     return Inst<U32>(Opcode::WorkgroupIdZ); | ||||
|     return U32{CompositeExtract(Inst(Opcode::WorkgroupId), 2)}; | ||||
| } | ||||
|  | ||||
| U32 IREmitter::LocalInvocationIdX() { | ||||
|     return Inst<U32>(Opcode::LocalInvocationIdX); | ||||
|     return U32{CompositeExtract(Inst(Opcode::LocalInvocationId), 0)}; | ||||
| } | ||||
|  | ||||
| U32 IREmitter::LocalInvocationIdY() { | ||||
|     return Inst<U32>(Opcode::LocalInvocationIdY); | ||||
|     return U32{CompositeExtract(Inst(Opcode::LocalInvocationId), 1)}; | ||||
| } | ||||
|  | ||||
| U32 IREmitter::LocalInvocationIdZ() { | ||||
|     return Inst<U32>(Opcode::LocalInvocationIdZ); | ||||
|     return U32{CompositeExtract(Inst(Opcode::LocalInvocationId), 2)}; | ||||
| } | ||||
|  | ||||
| U32 IREmitter::LoadGlobalU8(const U64& address) { | ||||
|   | ||||
| @@ -21,9 +21,9 @@ OPCODE(GetPred,                                             U1,             Pred | ||||
| OPCODE(SetPred,                                             Void,           Pred,           U1,                                             ) | ||||
| OPCODE(GetCbuf,                                             U32,            U32,            U32,                                            ) | ||||
| OPCODE(GetAttribute,                                        U32,            Attribute,                                                      ) | ||||
| OPCODE(SetAttribute,                                        U32,            Attribute,                                                      ) | ||||
| OPCODE(SetAttribute,                                        Void,           Attribute,      U32,                                            ) | ||||
| OPCODE(GetAttributeIndexed,                                 U32,            U32,                                                            ) | ||||
| OPCODE(SetAttributeIndexed,                                 U32,            U32,                                                            ) | ||||
| OPCODE(SetAttributeIndexed,                                 Void,           U32,            U32,                                            ) | ||||
| OPCODE(GetZFlag,                                            U1,             Void,                                                           ) | ||||
| OPCODE(GetSFlag,                                            U1,             Void,                                                           ) | ||||
| OPCODE(GetCFlag,                                            U1,             Void,                                                           ) | ||||
| @@ -32,12 +32,8 @@ OPCODE(SetZFlag,                                            Void,           U1, | ||||
| OPCODE(SetSFlag,                                            Void,           U1,                                                             ) | ||||
| OPCODE(SetCFlag,                                            Void,           U1,                                                             ) | ||||
| OPCODE(SetOFlag,                                            Void,           U1,                                                             ) | ||||
| OPCODE(WorkgroupIdX,                                        U32,                                                                            ) | ||||
| OPCODE(WorkgroupIdY,                                        U32,                                                                            ) | ||||
| OPCODE(WorkgroupIdZ,                                        U32,                                                                            ) | ||||
| OPCODE(LocalInvocationIdX,                                  U32,                                                                            ) | ||||
| OPCODE(LocalInvocationIdY,                                  U32,                                                                            ) | ||||
| OPCODE(LocalInvocationIdZ,                                  U32,                                                                            ) | ||||
| OPCODE(WorkgroupId,                                         U32x3,                                                                          ) | ||||
| OPCODE(LocalInvocationId,                                   U32x3,                                                                          ) | ||||
|  | ||||
| // Undefined | ||||
| OPCODE(Undef1,                                              U1,                                                                             ) | ||||
|   | ||||
| @@ -11,15 +11,15 @@ | ||||
|  | ||||
| namespace Shader::Maxwell { | ||||
|  | ||||
| template <auto visitor_method> | ||||
| template <auto method> | ||||
| static void Invoke(TranslatorVisitor& visitor, Location pc, u64 insn) { | ||||
|     using MethodType = decltype(visitor_method); | ||||
|     using MethodType = decltype(method); | ||||
|     if constexpr (std::is_invocable_r_v<void, MethodType, TranslatorVisitor&, Location, u64>) { | ||||
|         (visitor.*visitor_method)(pc, insn); | ||||
|         (visitor.*method)(pc, insn); | ||||
|     } else if constexpr (std::is_invocable_r_v<void, MethodType, TranslatorVisitor&, u64>) { | ||||
|         (visitor.*visitor_method)(insn); | ||||
|         (visitor.*method)(insn); | ||||
|     } else { | ||||
|         (visitor.*visitor_method)(); | ||||
|         (visitor.*method)(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ namespace Shader::Optimization { | ||||
| void IdentityRemovalPass(IR::Function& function) { | ||||
|     std::vector<IR::Inst*> to_invalidate; | ||||
|  | ||||
|     for (auto& block : function.blocks) { | ||||
|     for (IR::Block* const block : function.blocks) { | ||||
|         for (auto inst = block->begin(); inst != block->end();) { | ||||
|             const size_t num_args{inst->NumArgs()}; | ||||
|             for (size_t i = 0; i < num_args; ++i) { | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
|  | ||||
| #include <fmt/format.h> | ||||
|  | ||||
| #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||||
| #include "shader_recompiler/file_environment.h" | ||||
| #include "shader_recompiler/frontend/ir/basic_block.h" | ||||
| #include "shader_recompiler/frontend/ir/ir_emitter.h" | ||||
| @@ -51,18 +52,18 @@ void RunDatabase() { | ||||
| int main() { | ||||
|     // RunDatabase(); | ||||
|  | ||||
|     // FileEnvironment env{"D:\\Shaders\\Database\\test.bin"}; | ||||
|     FileEnvironment env{"D:\\Shaders\\Database\\Oninaki\\CS15C2FB1F0B965767.bin"}; | ||||
|     auto cfg{std::make_unique<Flow::CFG>(env, 0)}; | ||||
|     // fmt::print(stdout, "{}\n", cfg->Dot()); | ||||
|  | ||||
|     auto inst_pool{std::make_unique<ObjectPool<IR::Inst>>()}; | ||||
|     auto block_pool{std::make_unique<ObjectPool<IR::Block>>()}; | ||||
|  | ||||
|     for (int i = 0; i < 8192 * 4; ++i) { | ||||
|         void(inst_pool->Create(IR::Opcode::Void, 0)); | ||||
|     // FileEnvironment env{"D:\\Shaders\\Database\\test.bin"}; | ||||
|     FileEnvironment env{"D:\\Shaders\\Database\\Oninaki\\CS15C2FB1F0B965767.bin"}; | ||||
|     for (int i = 0; i < 1; ++i) { | ||||
|         block_pool->ReleaseContents(); | ||||
|         inst_pool->ReleaseContents(); | ||||
|         auto cfg{std::make_unique<Flow::CFG>(env, 0)}; | ||||
|         // fmt::print(stdout, "{}\n", cfg->Dot()); | ||||
|         IR::Program program{TranslateProgram(*inst_pool, *block_pool, env, *cfg)}; | ||||
|         // fmt::print(stdout, "{}\n", IR::DumpProgram(program)); | ||||
|         Backend::SPIRV::EmitSPIRV spirv{program}; | ||||
|     } | ||||
|  | ||||
|     IR::Program program{TranslateProgram(*inst_pool, *block_pool, env, *cfg)}; | ||||
|     fmt::print(stdout, "{}\n", IR::DumpProgram(program)); | ||||
| } | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,99 +0,0 @@ | ||||
| // Copyright 2019 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <array> | ||||
| #include <set> | ||||
| #include <vector> | ||||
|  | ||||
| #include "common/common_types.h" | ||||
| #include "video_core/engines/maxwell_3d.h" | ||||
| #include "video_core/engines/shader_type.h" | ||||
| #include "video_core/shader/registry.h" | ||||
| #include "video_core/shader/shader_ir.h" | ||||
|  | ||||
| namespace Vulkan { | ||||
|  | ||||
| class Device; | ||||
|  | ||||
| using Maxwell = Tegra::Engines::Maxwell3D::Regs; | ||||
| using UniformTexelEntry = VideoCommon::Shader::SamplerEntry; | ||||
| using SamplerEntry = VideoCommon::Shader::SamplerEntry; | ||||
| using StorageTexelEntry = VideoCommon::Shader::ImageEntry; | ||||
| using ImageEntry = VideoCommon::Shader::ImageEntry; | ||||
|  | ||||
| constexpr u32 DESCRIPTOR_SET = 0; | ||||
|  | ||||
| class ConstBufferEntry : public VideoCommon::Shader::ConstBuffer { | ||||
| public: | ||||
|     explicit constexpr ConstBufferEntry(const ConstBuffer& entry_, u32 index_) | ||||
|         : ConstBuffer{entry_}, index{index_} {} | ||||
|  | ||||
|     constexpr u32 GetIndex() const { | ||||
|         return index; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     u32 index{}; | ||||
| }; | ||||
|  | ||||
| struct GlobalBufferEntry { | ||||
|     u32 cbuf_index{}; | ||||
|     u32 cbuf_offset{}; | ||||
|     bool is_written{}; | ||||
| }; | ||||
|  | ||||
| struct ShaderEntries { | ||||
|     u32 NumBindings() const { | ||||
|         return static_cast<u32>(const_buffers.size() + global_buffers.size() + | ||||
|                                 uniform_texels.size() + samplers.size() + storage_texels.size() + | ||||
|                                 images.size()); | ||||
|     } | ||||
|  | ||||
|     std::vector<ConstBufferEntry> const_buffers; | ||||
|     std::vector<GlobalBufferEntry> global_buffers; | ||||
|     std::vector<UniformTexelEntry> uniform_texels; | ||||
|     std::vector<SamplerEntry> samplers; | ||||
|     std::vector<StorageTexelEntry> storage_texels; | ||||
|     std::vector<ImageEntry> images; | ||||
|     std::set<u32> attributes; | ||||
|     std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | ||||
|     std::size_t shader_length{}; | ||||
|     u32 enabled_uniform_buffers{}; | ||||
|     bool uses_warps{}; | ||||
| }; | ||||
|  | ||||
| struct Specialization final { | ||||
|     u32 base_binding{}; | ||||
|  | ||||
|     // Compute specific | ||||
|     std::array<u32, 3> workgroup_size{}; | ||||
|     u32 shared_memory_size{}; | ||||
|  | ||||
|     // Graphics specific | ||||
|     std::optional<float> point_size; | ||||
|     std::bitset<Maxwell::NumVertexAttributes> enabled_attributes; | ||||
|     std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; | ||||
|     bool ndc_minus_one_to_one{}; | ||||
|     bool early_fragment_tests{}; | ||||
|     float alpha_test_ref{}; | ||||
|     Maxwell::ComparisonOp alpha_test_func{}; | ||||
| }; | ||||
| // Old gcc versions don't consider this trivially copyable. | ||||
| // static_assert(std::is_trivially_copyable_v<Specialization>); | ||||
|  | ||||
| struct SPIRVShader { | ||||
|     std::vector<u32> code; | ||||
|     ShaderEntries entries; | ||||
| }; | ||||
|  | ||||
| ShaderEntries GenerateShaderEntries(const VideoCommon::Shader::ShaderIR& ir); | ||||
|  | ||||
| std::vector<u32> Decompile(const Device& device, const VideoCommon::Shader::ShaderIR& ir, | ||||
|                            Tegra::Engines::ShaderType stage, | ||||
|                            const VideoCommon::Shader::Registry& registry, | ||||
|                            const Specialization& specialization); | ||||
|  | ||||
| } // namespace Vulkan | ||||
		Reference in New Issue
	
	Block a user