#include "BdaShader.hpp" #include "SpirvBackend/SpirvBda.hpp" #include "SpirvBackend/SpirvMemory/SpirvTypes.hpp" #include "SpirvBackend/SpirvMemory/SpirvConstants.hpp" std::vector MakeBdaTestShader(std::uint64_t address, std::uint32_t bits, std::int64_t offset) { using namespace ShaderRecompiler; IrProgram program; program.Resources().stage = IrShaderStage::Compute; program.Info().usesDma = true; SpirvEmitterState state(program, {}); EmitBaseHeader(state.module, program); const auto define = [&](std::uint32_t binding) { const auto variable = state.module.DefineGlobalVariable(TypeStorageBufferPointer(state), spv::StorageClassStorageBuffer); state.module.AddAnnotation(spv::OpDecorate, variable, spv::DecorationDescriptorSet, 0u); state.module.AddAnnotation(spv::OpDecorate, variable, spv::DecorationBinding, binding); return variable; }; state.bdaPagetableVariable = define(0); state.faultBufferVariable = define(1); const auto output = define(2); DefineGetBdaPointer(state); const auto main = state.module.AllocateId(); state.module.AddFunction(spv::OpFunction, TypeVoid(state), main, spv::FunctionControlMaskNone, TypeFunction(state)); EmitLabel(state, state.module.AllocateId()); SpirvValueEmitContext ctx(state); auto& instruction = program.CreateValue(IrOpcode::LoadAddressU32, IrType::U32); MemoryFlags flags{}; flags.pc = 0x1234; instruction.SetFlags(flags); auto base = BdaConstant(state, address); if (offset != 0) base = AddBdaAddress(ctx, instruction, base, BdaConstant(state, offset < 0 ? std::uint64_t{0} - static_cast(offset) : static_cast(offset)), offset < 0); const auto value = EmitBdaRead(ctx, instruction, base, bits); state.module.AddFunction(spv::OpStore, BdaWord(state, output, ConstantU32(state, 0u)), value); state.module.AddFunction(spv::OpReturn); state.module.AddFunction(spv::OpFunctionEnd); state.module.AddExecutionMode(main, spv::ExecutionModeLocalSize, 1u, 1u, 1u); state.module.EmitEntryPoint(spv::ExecutionModelGLCompute, main, "main", {}); return state.module.Finalize(); }