spirv: Add lower fp16 to fp32 pass
This commit is contained in:
		| @@ -30,8 +30,11 @@ EmitContext::EmitContext(IR::Program& program) : Sirit::Module(0x00010000) { | ||||
|     DefineCommonTypes(program.info); | ||||
|     DefineCommonConstants(); | ||||
|     DefineSpecialVariables(program.info); | ||||
|     DefineConstantBuffers(program.info); | ||||
|     DefineStorageBuffers(program.info); | ||||
|  | ||||
|     u32 binding{}; | ||||
|     DefineConstantBuffers(program.info, binding); | ||||
|     DefineStorageBuffers(program.info, binding); | ||||
|  | ||||
|     DefineLabels(program); | ||||
| } | ||||
|  | ||||
| @@ -58,6 +61,12 @@ void EmitContext::DefineCommonTypes(const Info& info) { | ||||
|  | ||||
|     U1 = Name(TypeBool(), "u1"); | ||||
|  | ||||
|     // TODO: Conditionally define these | ||||
|     AddCapability(spv::Capability::Int16); | ||||
|     AddCapability(spv::Capability::Int64); | ||||
|     U16 = Name(TypeInt(16, false), "u16"); | ||||
|     U64 = Name(TypeInt(64, false), "u64"); | ||||
|  | ||||
|     F32.Define(*this, TypeFloat(32), "f32"); | ||||
|     U32.Define(*this, TypeInt(32, false), "u32"); | ||||
|  | ||||
| @@ -95,12 +104,12 @@ void EmitContext::DefineSpecialVariables(const Info& info) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitContext::DefineConstantBuffers(const Info& info) { | ||||
| void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) { | ||||
|     if (info.constant_buffer_descriptors.empty()) { | ||||
|         return; | ||||
|     } | ||||
|     const Id array_type{TypeArray(U32[1], Constant(U32[1], 4096))}; | ||||
|     Decorate(array_type, spv::Decoration::ArrayStride, 16U); | ||||
|     Decorate(array_type, spv::Decoration::ArrayStride, 4U); | ||||
|  | ||||
|     const Id struct_type{TypeStruct(array_type)}; | ||||
|     Name(struct_type, "cbuf_block"); | ||||
| @@ -111,18 +120,19 @@ void EmitContext::DefineConstantBuffers(const Info& info) { | ||||
|     const Id uniform_type{TypePointer(spv::StorageClass::Uniform, struct_type)}; | ||||
|     uniform_u32 = TypePointer(spv::StorageClass::Uniform, U32[1]); | ||||
|  | ||||
|     u32 binding{}; | ||||
|     u32 index{}; | ||||
|     for (const Info::ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) { | ||||
|         const Id id{AddGlobalVariable(uniform_type, spv::StorageClass::Uniform)}; | ||||
|         Decorate(id, spv::Decoration::Binding, binding); | ||||
|         Decorate(id, spv::Decoration::DescriptorSet, 0U); | ||||
|         Name(id, fmt::format("c{}", desc.index)); | ||||
|         std::fill_n(cbufs.data() + desc.index, desc.count, id); | ||||
|         index += desc.count; | ||||
|         binding += desc.count; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitContext::DefineStorageBuffers(const Info& info) { | ||||
| void EmitContext::DefineStorageBuffers(const Info& info, u32& binding) { | ||||
|     if (info.storage_buffers_descriptors.empty()) { | ||||
|         return; | ||||
|     } | ||||
| @@ -140,13 +150,14 @@ void EmitContext::DefineStorageBuffers(const Info& info) { | ||||
|     const Id storage_type{TypePointer(spv::StorageClass::StorageBuffer, struct_type)}; | ||||
|     storage_u32 = TypePointer(spv::StorageClass::StorageBuffer, U32[1]); | ||||
|  | ||||
|     u32 binding{}; | ||||
|     u32 index{}; | ||||
|     for (const Info::StorageBufferDescriptor& desc : info.storage_buffers_descriptors) { | ||||
|         const Id id{AddGlobalVariable(storage_type, spv::StorageClass::StorageBuffer)}; | ||||
|         Decorate(id, spv::Decoration::Binding, binding); | ||||
|         Decorate(id, spv::Decoration::DescriptorSet, 0U); | ||||
|         Name(id, fmt::format("ssbo{}", binding)); | ||||
|         std::fill_n(ssbos.data() + binding, desc.count, id); | ||||
|         Name(id, fmt::format("ssbo{}", index)); | ||||
|         std::fill_n(ssbos.data() + index, desc.count, id); | ||||
|         index += desc.count; | ||||
|         binding += desc.count; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -37,6 +37,8 @@ public: | ||||
|  | ||||
|     Id void_id{}; | ||||
|     Id U1{}; | ||||
|     Id U16{}; | ||||
|     Id U64{}; | ||||
|     VectorTypes F32; | ||||
|     VectorTypes U32; | ||||
|     VectorTypes F16; | ||||
| @@ -59,8 +61,8 @@ private: | ||||
|     void DefineCommonTypes(const Info& info); | ||||
|     void DefineCommonConstants(); | ||||
|     void DefineSpecialVariables(const Info& info); | ||||
|     void DefineConstantBuffers(const Info& info); | ||||
|     void DefineStorageBuffers(const Info& info); | ||||
|     void DefineConstantBuffers(const Info& info, u32& binding); | ||||
|     void DefineStorageBuffers(const Info& info, u32& binding); | ||||
|     void DefineLabels(IR::Program& program); | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -14,6 +14,8 @@ | ||||
| #include "shader_recompiler/frontend/ir/microinstruction.h" | ||||
| #include "shader_recompiler/frontend/ir/program.h" | ||||
|  | ||||
| #pragma optimize("", off) | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
| namespace { | ||||
| template <class Func> | ||||
|   | ||||
| @@ -79,26 +79,27 @@ void EmitWriteStorageU16(EmitContext& ctx); | ||||
| void EmitWriteStorageS16(EmitContext& ctx); | ||||
| void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, | ||||
|                         Id value); | ||||
| void EmitWriteStorage64(EmitContext& ctx); | ||||
| void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, | ||||
|                         Id value); | ||||
| 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); | ||||
| Id EmitCompositeConstructU32x2(EmitContext& ctx, Id e1, Id e2); | ||||
| Id EmitCompositeConstructU32x3(EmitContext& ctx, Id e1, Id e2, Id e3); | ||||
| Id EmitCompositeConstructU32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4); | ||||
| Id EmitCompositeExtractU32x2(EmitContext& ctx, Id composite, u32 index); | ||||
| Id EmitCompositeExtractU32x3(EmitContext& ctx, Id composite, u32 index); | ||||
| Id EmitCompositeExtractU32x4(EmitContext& ctx, Id composite, u32 index); | ||||
| void EmitCompositeConstructF16x2(EmitContext& ctx); | ||||
| void EmitCompositeConstructF16x3(EmitContext& ctx); | ||||
| void EmitCompositeConstructF16x4(EmitContext& ctx); | ||||
| void EmitCompositeExtractF16x2(EmitContext& ctx); | ||||
| void EmitCompositeExtractF16x3(EmitContext& ctx); | ||||
| void EmitCompositeExtractF16x4(EmitContext& ctx); | ||||
| Id EmitCompositeExtractF16x2(EmitContext& ctx, Id composite, u32 index); | ||||
| Id EmitCompositeExtractF16x3(EmitContext& ctx, Id composite, u32 index); | ||||
| Id EmitCompositeExtractF16x4(EmitContext& ctx, Id composite, u32 index); | ||||
| void EmitCompositeConstructF32x2(EmitContext& ctx); | ||||
| void EmitCompositeConstructF32x3(EmitContext& ctx); | ||||
| void EmitCompositeConstructF32x4(EmitContext& ctx); | ||||
| void EmitCompositeExtractF32x2(EmitContext& ctx); | ||||
| void EmitCompositeExtractF32x3(EmitContext& ctx); | ||||
| void EmitCompositeExtractF32x4(EmitContext& ctx); | ||||
| Id EmitCompositeExtractF32x2(EmitContext& ctx, Id composite, u32 index); | ||||
| Id EmitCompositeExtractF32x3(EmitContext& ctx, Id composite, u32 index); | ||||
| Id EmitCompositeExtractF32x4(EmitContext& ctx, Id composite, u32 index); | ||||
| void EmitCompositeConstructF64x2(EmitContext& ctx); | ||||
| void EmitCompositeConstructF64x3(EmitContext& ctx); | ||||
| void EmitCompositeConstructF64x4(EmitContext& ctx); | ||||
| @@ -116,11 +117,13 @@ 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); | ||||
| Id EmitUnpackUint2x32(EmitContext& ctx, Id value); | ||||
| Id EmitPackFloat2x16(EmitContext& ctx, Id value); | ||||
| Id EmitUnpackFloat2x16(EmitContext& ctx, Id value); | ||||
| Id EmitPackHalf2x16(EmitContext& ctx, Id value); | ||||
| Id EmitUnpackHalf2x16(EmitContext& ctx, Id value); | ||||
| Id EmitPackDouble2x32(EmitContext& ctx, Id value); | ||||
| Id EmitUnpackDouble2x32(EmitContext& ctx, Id value); | ||||
| void EmitGetZeroFromOp(EmitContext& ctx); | ||||
| void EmitGetSignFromOp(EmitContext& ctx); | ||||
| void EmitGetCarryFromOp(EmitContext& ctx); | ||||
| @@ -159,18 +162,18 @@ 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 EmitFPRoundEven16(EmitContext& ctx, Id value); | ||||
| Id EmitFPRoundEven32(EmitContext& ctx, Id value); | ||||
| Id EmitFPRoundEven64(EmitContext& ctx, Id value); | ||||
| Id EmitFPFloor16(EmitContext& ctx, Id value); | ||||
| Id EmitFPFloor32(EmitContext& ctx, Id value); | ||||
| Id EmitFPFloor64(EmitContext& ctx, Id value); | ||||
| Id EmitFPCeil16(EmitContext& ctx, Id value); | ||||
| Id EmitFPCeil32(EmitContext& ctx, Id value); | ||||
| Id EmitFPCeil64(EmitContext& ctx, Id value); | ||||
| Id EmitFPTrunc16(EmitContext& ctx, Id value); | ||||
| Id EmitFPTrunc32(EmitContext& ctx, Id value); | ||||
| Id EmitFPTrunc64(EmitContext& ctx, Id value); | ||||
| Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
| void EmitIAdd64(EmitContext& ctx); | ||||
| Id EmitISub32(EmitContext& ctx, Id a, Id b); | ||||
| @@ -201,25 +204,25 @@ 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); | ||||
| Id EmitConvertS16F16(EmitContext& ctx, Id value); | ||||
| Id EmitConvertS16F32(EmitContext& ctx, Id value); | ||||
| Id EmitConvertS16F64(EmitContext& ctx, Id value); | ||||
| Id EmitConvertS32F16(EmitContext& ctx, Id value); | ||||
| Id EmitConvertS32F32(EmitContext& ctx, Id value); | ||||
| Id EmitConvertS32F64(EmitContext& ctx, Id value); | ||||
| Id EmitConvertS64F16(EmitContext& ctx, Id value); | ||||
| Id EmitConvertS64F32(EmitContext& ctx, Id value); | ||||
| Id EmitConvertS64F64(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU16F16(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU16F32(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU16F64(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU32F16(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU32F32(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU32F64(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU64F16(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU64F32(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU64F64(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU64U32(EmitContext& ctx, Id value); | ||||
| Id EmitConvertU32U64(EmitContext& ctx, Id value); | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
|   | ||||
| @@ -34,24 +34,32 @@ void EmitPackUint2x32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitUnpackUint2x32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitUnpackUint2x32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpBitcast(ctx.U32[2], value); | ||||
| } | ||||
|  | ||||
| void EmitPackFloat2x16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitPackFloat2x16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpBitcast(ctx.U32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitUnpackFloat2x16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitUnpackFloat2x16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpBitcast(ctx.F16[2], value); | ||||
| } | ||||
|  | ||||
| void EmitPackDouble2x32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitPackHalf2x16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpPackHalf2x16(ctx.U32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitUnpackDouble2x32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitUnpackHalf2x16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpUnpackHalf2x16(ctx.F32[2], value); | ||||
| } | ||||
|  | ||||
| Id EmitPackDouble2x32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpBitcast(ctx.F64[1], value); | ||||
| } | ||||
|  | ||||
| Id EmitUnpackDouble2x32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpBitcast(ctx.U32[2], value); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
|   | ||||
| @@ -6,28 +6,28 @@ | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitCompositeConstructU32x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeConstructU32x2(EmitContext& ctx, Id e1, Id e2) { | ||||
|     return ctx.OpCompositeConstruct(ctx.U32[2], e1, e2); | ||||
| } | ||||
|  | ||||
| void EmitCompositeConstructU32x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeConstructU32x3(EmitContext& ctx, Id e1, Id e2, Id e3) { | ||||
|     return ctx.OpCompositeConstruct(ctx.U32[3], e1, e2, e3); | ||||
| } | ||||
|  | ||||
| void EmitCompositeConstructU32x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeConstructU32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4) { | ||||
|     return ctx.OpCompositeConstruct(ctx.U32[4], e1, e2, e3, e4); | ||||
| } | ||||
|  | ||||
| void EmitCompositeExtractU32x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeExtractU32x2(EmitContext& ctx, Id composite, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.U32[1], composite, index); | ||||
| } | ||||
|  | ||||
| Id EmitCompositeExtractU32x3(EmitContext& ctx, Id vector, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.U32[1], vector, index); | ||||
| Id EmitCompositeExtractU32x3(EmitContext& ctx, Id composite, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.U32[1], composite, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeExtractU32x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeExtractU32x4(EmitContext& ctx, Id composite, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.U32[1], composite, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeConstructF16x2(EmitContext&) { | ||||
| @@ -42,16 +42,16 @@ void EmitCompositeConstructF16x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitCompositeExtractF16x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeExtractF16x2(EmitContext& ctx, Id composite, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.F16[1], composite, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeExtractF16x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeExtractF16x3(EmitContext& ctx, Id composite, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.F16[1], composite, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeExtractF16x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeExtractF16x4(EmitContext& ctx, Id composite, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.F16[1], composite, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeConstructF32x2(EmitContext&) { | ||||
| @@ -66,16 +66,16 @@ void EmitCompositeConstructF32x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitCompositeExtractF32x2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeExtractF32x2(EmitContext& ctx, Id composite, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.F32[1], composite, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeExtractF32x3(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeExtractF32x3(EmitContext& ctx, Id composite, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.F32[1], composite, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeExtractF32x4(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitCompositeExtractF32x4(EmitContext& ctx, Id composite, u32 index) { | ||||
|     return ctx.OpCompositeExtract(ctx.F32[1], composite, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeConstructF64x2(EmitContext&) { | ||||
|   | ||||
| @@ -11,7 +11,7 @@ void EmitBranch(EmitContext& ctx, IR::Block* label) { | ||||
| } | ||||
|  | ||||
| void EmitBranchConditional(EmitContext& ctx, Id condition, IR::Block* true_label, | ||||
|                                       IR::Block* false_label) { | ||||
|                            IR::Block* false_label) { | ||||
|     ctx.OpBranchConditional(condition, true_label->Definition<Id>(), false_label->Definition<Id>()); | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										89
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/shader_recompiler/backend/spirv/emit_spirv_convert.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 { | ||||
|  | ||||
| Id EmitConvertS16F16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); | ||||
| } | ||||
|  | ||||
| Id EmitConvertS16F32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); | ||||
| } | ||||
|  | ||||
| Id EmitConvertS16F64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); | ||||
| } | ||||
|  | ||||
| Id EmitConvertS32F16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToS(ctx.U32[1], value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertS32F32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToS(ctx.U32[1], value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertS32F64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToS(ctx.U32[1], value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertS64F16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToS(ctx.U64, value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertS64F32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToS(ctx.U64, value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertS64F64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToS(ctx.U64, value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU16F16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU16F32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU16F64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU32F16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToU(ctx.U32[1], value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU32F32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToU(ctx.U32[1], value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU32F64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToU(ctx.U32[1], value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU64F16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToU(ctx.U64, value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU64F32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToU(ctx.U64, value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU64F64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpConvertFToU(ctx.U64, value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU64U32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpUConvert(ctx.U64, value); | ||||
| } | ||||
|  | ||||
| Id EmitConvertU32U64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpUConvert(ctx.U32[1], value); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
| @@ -169,52 +169,52 @@ void EmitFPSaturate64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitFPRoundEven16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPRoundEven16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpRoundEven(ctx.F16[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPRoundEven32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPRoundEven32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpRoundEven(ctx.F32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPRoundEven64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPRoundEven64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpRoundEven(ctx.F64[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPFloor16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPFloor16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpFloor(ctx.F16[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPFloor32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPFloor32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpFloor(ctx.F32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPFloor64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPFloor64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpFloor(ctx.F64[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPCeil16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPCeil16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpCeil(ctx.F16[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPCeil32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPCeil32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpCeil(ctx.F32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPCeil64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPCeil64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpCeil(ctx.F64[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPTrunc16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPTrunc16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpTrunc(ctx.F16[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPTrunc32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPTrunc32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpTrunc(ctx.F32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPTrunc64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPTrunc64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpTrunc(ctx.F64[1], value); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
|   | ||||
| @@ -113,20 +113,4 @@ Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs) { | ||||
|     return ctx.OpUGreaterThanEqual(ctx.U1, lhs, rhs); | ||||
| } | ||||
|  | ||||
| void EmitLogicalOr(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitLogicalAnd(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitLogicalXor(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitLogicalNot(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
|   | ||||
| @@ -6,83 +6,19 @@ | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
|  | ||||
| void EmitConvertS16F16(EmitContext&) { | ||||
| void EmitLogicalOr(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertS16F32(EmitContext&) { | ||||
| void EmitLogicalAnd(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertS16F64(EmitContext&) { | ||||
| void EmitLogicalXor(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertS32F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertS32F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertS32F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertS64F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertS64F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertS64F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU16F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU16F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU16F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU32F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU32F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU32F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU64F16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU64F32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU64F64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU64U32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitConvertU32U64(EmitContext&) { | ||||
| void EmitLogicalNot(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -94,8 +94,7 @@ void EmitLoadStorageS16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitLoadStorage32(EmitContext& ctx, const IR::Value& binding, | ||||
|                                 const IR::Value& offset) { | ||||
| Id EmitLoadStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | ||||
|     if (!binding.IsImmediate()) { | ||||
|         throw NotImplementedException("Dynamic storage buffer indexing"); | ||||
|     } | ||||
| @@ -129,8 +128,8 @@ void EmitWriteStorageS16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, | ||||
|                                    const IR::Value& offset, Id value) { | ||||
| void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, | ||||
|                         Id value) { | ||||
|     if (!binding.IsImmediate()) { | ||||
|         throw NotImplementedException("Dynamic storage buffer indexing"); | ||||
|     } | ||||
| @@ -140,8 +139,19 @@ void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, | ||||
|     ctx.OpStore(pointer, value); | ||||
| } | ||||
|  | ||||
| void EmitWriteStorage64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, | ||||
|                         Id value) { | ||||
|     if (!binding.IsImmediate()) { | ||||
|         throw NotImplementedException("Dynamic storage buffer indexing"); | ||||
|     } | ||||
|     // TODO: Support reinterpreting bindings, guaranteed to be aligned | ||||
|     const Id ssbo{ctx.ssbos[binding.U32()]}; | ||||
|     const Id low_index{StorageIndex(ctx, offset, sizeof(u32))}; | ||||
|     const Id high_index{ctx.OpIAdd(ctx.U32[1], low_index, ctx.Constant(ctx.U32[1], 1U))}; | ||||
|     const Id low_pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, low_index)}; | ||||
|     const Id high_pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, high_index)}; | ||||
|     ctx.OpStore(low_pointer, ctx.OpCompositeExtract(ctx.U32[1], value, 0U)); | ||||
|     ctx.OpStore(high_pointer, ctx.OpCompositeExtract(ctx.U32[1], value, 1U)); | ||||
| } | ||||
|  | ||||
| void EmitWriteStorage128(EmitContext&) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user