Files
UnrealEngine/Engine/Source/Runtime/VectorVM/Private/VectorVMBridge.cpp
2025-05-18 13:04:45 +08:00

201 lines
7.8 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "VectorVMBridge.h"
#include "Serialization/MemoryReader.h"
#include "Serialization/MemoryWriter.h"
#include "VectorVMEditor.h"
#include "VectorVMOptimizer.h"
#include "VectorVMTypes.h"
namespace VectorVM::Bridge
{
struct FRuntimeContextData
{
FRuntimeContextData(const Runtime::FVectorVMRuntimeContext& Context)
: NumBytecodeBytes(Context.NumBytecodeBytes)
, MaxOutputDataSet(Context.MaxOutputDataSet)
, NumConstsAlloced(Context.NumConstsAlloced)
, NumTempRegisters(Context.NumTempRegisters)
, NumConstsRemapped(Context.NumConstsRemapped)
, NumInputsRemapped(Context.NumInputsRemapped)
, NumNoAdvanceInputs(Context.NumNoAdvanceInputs)
, NumInputDataSets(Context.NumInputDataSets)
, NumOutputsRemapped(Context.NumOutputsRemapped)
, NumOutputInstructions(Context.NumOutputInstructions)
, NumExtFns(Context.NumExtFns)
, MaxExtFnRegisters(Context.MaxExtFnRegisters)
, NumDummyRegsReq(Context.NumDummyRegsReq)
, MaxExtFnUsed(Context.MaxExtFnUsed)
, Flags(Context.Flags)
, HashId(Context.HashId)
{}
FRuntimeContextData(TConstArrayView<uint8> ContextData)
{
FMemoryReaderView Ar(ContextData);
Ar << *this;
}
void CopyToContext(Runtime::FVectorVMRuntimeContext& Context) const
{
Context.NumBytecodeBytes = NumBytecodeBytes;
Context.MaxOutputDataSet = MaxOutputDataSet;
Context.NumConstsAlloced = NumConstsAlloced;
Context.NumTempRegisters = NumTempRegisters;
Context.NumConstsRemapped = NumConstsRemapped;
Context.NumInputsRemapped = NumInputsRemapped;
Context.NumNoAdvanceInputs = NumNoAdvanceInputs;
Context.NumInputDataSets = NumInputDataSets;
Context.NumOutputsRemapped = NumOutputsRemapped;
Context.NumOutputInstructions = NumOutputInstructions;
Context.NumExtFns = NumExtFns;
Context.MaxExtFnRegisters = MaxExtFnRegisters;
Context.NumDummyRegsReq = NumDummyRegsReq;
Context.MaxExtFnUsed = MaxExtFnUsed;
Context.Flags = Flags;
Context.HashId = HashId;
}
friend FArchive& operator<<(FArchive& Ar, FRuntimeContextData& ContextInfo);
uint32 NumBytecodeBytes;
uint32 MaxOutputDataSet;
uint16 NumConstsAlloced;
uint32 NumTempRegisters;
uint16 NumConstsRemapped;
uint16 NumInputsRemapped;
uint16 NumNoAdvanceInputs;
uint16 NumInputDataSets;
uint16 NumOutputsRemapped;
uint16 NumOutputInstructions;
uint32 NumExtFns;
uint32 MaxExtFnRegisters;
uint32 NumDummyRegsReq;
int32 MaxExtFnUsed;
uint32 Flags;
uint64 HashId;
};
FArchive& operator<<(FArchive& Ar, FRuntimeContextData& ContextInfo)
{
Ar << ContextInfo.NumBytecodeBytes;
Ar << ContextInfo.MaxOutputDataSet;
Ar << ContextInfo.NumConstsAlloced;
Ar << ContextInfo.NumTempRegisters;
Ar << ContextInfo.NumConstsRemapped;
Ar << ContextInfo.NumInputsRemapped;
Ar << ContextInfo.NumNoAdvanceInputs;
Ar << ContextInfo.NumInputDataSets;
Ar << ContextInfo.NumOutputsRemapped;
Ar << ContextInfo.NumOutputInstructions;
Ar << ContextInfo.NumExtFns;
Ar << ContextInfo.MaxExtFnRegisters;
Ar << ContextInfo.NumDummyRegsReq;
Ar << ContextInfo.MaxExtFnUsed;
Ar << ContextInfo.Flags;
Ar << ContextInfo.HashId;
return Ar;
}
struct FContextInfoLayout
{
FContextInfoLayout(const FRuntimeContextData& Context)
: PropertySize(sizeof(Context))
, BytecodeSize(Context.NumBytecodeBytes)
, ConstRemapSize(Context.NumConstsRemapped * sizeof(uint16))
, InputRemapSize(Context.NumInputsRemapped * sizeof(uint16))
, InputDataSetOffsetsSize(Context.NumInputDataSets * 8 * sizeof(uint16))
, OutputRemapDataSetIdxSize(Context.NumOutputsRemapped * sizeof(uint8))
, OutputRemapDataTypeSize(Context.NumOutputsRemapped * sizeof(uint16))
, OutputRemapDstSize(Context.NumOutputsRemapped * sizeof(uint16))
, ExtFnSize(Context.NumExtFns * sizeof(FVectorVMExtFunctionData))
, PropertyOffset(0)
, BytecodeOffset(Align(PropertyOffset + PropertySize, 16))
, ConstRemapOffset(Align(BytecodeOffset + BytecodeSize, 16))
, InputRemapOffset(Align(ConstRemapOffset + ConstRemapSize, 16))
, InputDataSetOffsetsOffset(Align(InputRemapOffset + InputRemapSize, 16))
, OutputRemapDataSetIdxOffset(Align(InputDataSetOffsetsOffset + InputDataSetOffsetsSize, 16))
, OutputRemapDataTypeOffset(Align(OutputRemapDataSetIdxOffset + OutputRemapDataSetIdxSize, 16))
, OutputRemapDstOffset(Align(OutputRemapDataTypeOffset + OutputRemapDataTypeSize, 16))
, ExtFnOffset(Align(OutputRemapDstOffset + OutputRemapDstSize, 16))
, TotalSize(Align(ExtFnOffset + ExtFnSize, 16))
{
}
const uint32 PropertySize;
const uint32 BytecodeSize;
const uint32 ConstRemapSize;
const uint32 InputRemapSize;
const uint32 InputDataSetOffsetsSize;
const uint32 OutputRemapDataSetIdxSize;
const uint32 OutputRemapDataTypeSize;
const uint32 OutputRemapDstSize;
const uint32 ExtFnSize;
const size_t PropertyOffset;
const size_t BytecodeOffset;
const size_t ConstRemapOffset;
const size_t InputRemapOffset;
const size_t InputDataSetOffsetsOffset;
const size_t OutputRemapDataSetIdxOffset;
const size_t OutputRemapDataTypeOffset;
const size_t OutputRemapDstOffset;
const size_t ExtFnOffset;
const size_t TotalSize;
};
#if WITH_EDITORONLY_DATA
void FreezeOptimizerContext(const Optimizer::FVectorVMOptimizerContext& Context, TArray<uint8>& ContextData)
{
FRuntimeContextData RuntimeData(Context);
FContextInfoLayout Layout(RuntimeData);
ContextData.SetNumZeroed(Layout.TotalSize);
uint8* BufferData = ContextData.GetData();
FMemoryWriter Ar(ContextData);
Ar << RuntimeData;
FMemory::Memcpy(BufferData + Layout.BytecodeOffset, Context.OutputBytecode, Layout.BytecodeSize);
FMemory::Memcpy(BufferData + Layout.ConstRemapOffset, Context.ConstRemap[1], Layout.ConstRemapSize);
FMemory::Memcpy(BufferData + Layout.InputRemapOffset, Context.InputRemapTable, Layout.InputRemapSize);
FMemory::Memcpy(BufferData + Layout.InputDataSetOffsetsOffset, Context.InputDataSetOffsets, Layout.InputDataSetOffsetsSize);
FMemory::Memcpy(BufferData + Layout.OutputRemapDataSetIdxOffset, Context.OutputRemapDataSetIdx, Layout.OutputRemapDataSetIdxSize);
FMemory::Memcpy(BufferData + Layout.OutputRemapDataTypeOffset, Context.OutputRemapDataType, Layout.OutputRemapDataTypeSize);
FMemory::Memcpy(BufferData + Layout.OutputRemapDstOffset, Context.OutputRemapDst, Layout.OutputRemapDstSize);
FMemory::Memcpy(BufferData + Layout.ExtFnOffset, Context.ExtFnTable, Layout.ExtFnSize);
// external function pointers
FVectorVMExtFunctionData* ExtFunctionTable = reinterpret_cast<FVectorVMExtFunctionData*>(BufferData + Layout.ExtFnOffset);
for (uint32 ExtFunctionIt = 0; ExtFunctionIt < Context.NumExtFns; ++ExtFunctionIt)
{
ExtFunctionTable[ExtFunctionIt].Function = nullptr;
}
}
#endif // WITH_EDITORONLY_DATA
void ThawRuntimeContext(TConstArrayView<uint8> ContextData, Runtime::FVectorVMRuntimeContext& Context)
{
FMemory::Memzero(Context);
FRuntimeContextData RuntimeData(ContextData);
FContextInfoLayout Layout(RuntimeData);
RuntimeData.CopyToContext(Context);
const uint8* BufferData = ContextData.GetData();
Context.OutputBytecode = const_cast<uint8*>(reinterpret_cast<const uint8*>(BufferData + Layout.BytecodeOffset));
Context.ConstRemap[1] = const_cast<uint16*>(reinterpret_cast<const uint16*>(BufferData + Layout.ConstRemapOffset));
Context.InputRemapTable = const_cast<uint16*>(reinterpret_cast<const uint16*>(BufferData + Layout.InputRemapOffset));
Context.InputDataSetOffsets = const_cast<uint16*>(reinterpret_cast<const uint16*>(BufferData + Layout.InputDataSetOffsetsOffset));
Context.OutputRemapDataSetIdx = const_cast<uint8*>(reinterpret_cast<const uint8*>(BufferData + Layout.OutputRemapDataSetIdxOffset));
Context.OutputRemapDataType = const_cast<uint16*>(reinterpret_cast<const uint16*>(BufferData + Layout.OutputRemapDataTypeOffset));
Context.OutputRemapDst = const_cast<uint16*>(reinterpret_cast<const uint16*>(BufferData + Layout.OutputRemapDstOffset));
Context.ExtFnTable = const_cast<FVectorVMExtFunctionData*>(reinterpret_cast<const FVectorVMExtFunctionData*>(BufferData + Layout.ExtFnOffset));
}
} // VectorVM::Bridge