// Copyright 2021 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include #include "shader_recompiler/backend/spirv/emit_spirv.h" namespace Shader::Backend::SPIRV { static Id StorageIndex(EmitContext& ctx, const IR::Value& offset, size_t element_size) { if (offset.IsImmediate()) { const u32 imm_offset{static_cast(offset.U32() / element_size)}; return ctx.Constant(ctx.U32[1], imm_offset); } const u32 shift{static_cast(std::countr_zero(element_size))}; const Id index{ctx.Def(offset)}; if (shift == 0) { return index; } const Id shift_id{ctx.Constant(ctx.U32[1], shift)}; return ctx.OpShiftRightLogical(ctx.U32[1], index, shift_id); } 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, const IR::Value& offset) { if (!binding.IsImmediate()) { throw NotImplementedException("Dynamic storage buffer indexing"); } const Id ssbo{ctx.ssbos[binding.U32()]}; const Id index{StorageIndex(ctx, offset, sizeof(u32))}; const Id pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, index)}; return ctx.OpLoad(ctx.U32[1], pointer); } 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, const IR::Value& binding, const IR::Value& offset, Id value) { if (!binding.IsImmediate()) { throw NotImplementedException("Dynamic storage buffer indexing"); } const Id ssbo{ctx.ssbos[binding.U32()]}; const Id index{StorageIndex(ctx, offset, sizeof(u32))}; const Id pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, index)}; ctx.OpStore(pointer, value); } void EmitSPIRV::EmitWriteStorage64(EmitContext&) { throw NotImplementedException("SPIR-V Instruction"); } void EmitSPIRV::EmitWriteStorage128(EmitContext&) { throw NotImplementedException("SPIR-V Instruction"); } } // namespace Shader::Backend::SPIRV