41 lines
2.2 KiB
C++
41 lines
2.2 KiB
C++
#include "BdaShader.hpp"
|
|
#include "SpirvBackend/SpirvBda.hpp"
|
|
#include "SpirvBackend/SpirvMemory/SpirvTypes.hpp"
|
|
#include "SpirvBackend/SpirvMemory/SpirvConstants.hpp"
|
|
|
|
std::vector<std::uint32_t> 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<std::uint64_t>(offset) : static_cast<std::uint64_t>(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();
|
|
}
|