(1)
TypeOffsetTable 是 Primitive Type 相同 Primitive 的结束偏移,不是开始偏移,第一个类型开始偏移是 0,第一个类型结束偏移,是第一个类型的个数
Source\Runtime\Renderer\Private\RendererScene.cpp
FTypeOffsetTableEntry& NextEntry = TypeOffsetTable[TypeIndex];
(1)
Primitives SOA 数据,不会修改这个数据结构,PersistentPrimitiveIdToIndexMap 是进行二次映射,映射到 Primitives,PersistentPrimitiveIdToIndexMap 下标索引和 Primitives 一致,PersistentPrimitiveIdToIndexMap 下标索引内容,对应 Primitives 索引
Primitives[SourceIndex]->PackedIndex 表示应该放置的数组下标
Source\Runtime\Renderer\Private\RendererScene.cpp
FPersistentPrimitiveIndex MovedPersisitentIndex = Primitives[DestIndex]->PersistentIndex;
PersistentPrimitiveIdToIndexMap[MovedPersisitentIndex.Index] = SourceIndex;
Primitives[SourceIndex]->PackedIndex = DestIndex;
(1)
需要更新 instance 条件,UpdatedInstances 和 AddedLocalPrimitiveSceneInfos
PendingAllocateInstanceIds.Reserve(UpdatedInstances.Num() + AddedLocalPrimitiveSceneInfos.Num());
(1)
primitive 更新条件 AddedPrimitiveSceneInfos 和 UpdatedTransforms 和 UpdatedInstances,不太明白为什么 UpdatedInstances 更新需要修改 primitive
const int32 SceneInfosContainerReservedSize = AddedPrimitiveSceneInfos.Num() + UpdatedTransforms.Num() + UpdatedInstances.Num();
(1)
GPUSceneInstanceSceneDataRW 是 float4 的 soa
Saved\ShaderDebugInfo\PCD3D_SM6\Global\FGPUSceneSetInstancePrimitiveIdCS\0\GPUSceneDataManagement.usf
RWStructuredBuffer<float4> GPUSceneInstanceSceneDataRW;
float4 LoadInstanceSceneDataElement(uint Index)
{
return GPUSceneInstanceSceneDataRW[Index];
}
(1)
Source\Runtime\Engine\Public\InstanceUniformShaderParameters.h
ENGINE_API void Build
(
uint32 PrimitiveId,
uint32 RelativeId,
uint32 InstanceFlags,
uint32 LastUpdateFrame,
uint32 CustomDataCount,
float RandomID,
bool bIsVisible = true
);
(1)
Source\Runtime\Renderer\Private\GPUScene.cpp
InstanceUploadInfo.InstanceSceneDataBuffers = PrimitiveSceneInfo->GetInstanceSceneDataBuffers();
if (InstanceUploadInfo.InstanceSceneDataBuffers)
{
const FInstanceSceneDataBuffers::FReadView InstanceSceneDataBuffers = InstanceUploadInfo.InstanceSceneDataBuffers->GetReadView();
InstanceUploadInfo.NumInstances = InstanceUploadInfo.InstanceSceneDataBuffers->GetNumInstances();
InstanceUploadInfo.InstanceFlags = PackFlags(InstanceSceneDataBuffers.Flags);
InstanceUploadInfo.InstanceLightShadowUVBias = InstanceSceneDataBuffers.InstanceLightShadowUVBias;
InstanceUploadInfo.InstanceCustomData = InstanceSceneDataBuffers.InstanceCustomData;
InstanceUploadInfo.InstanceRandomID = InstanceSceneDataBuffers.InstanceRandomIDs;
InstanceUploadInfo.InstanceHierarchyOffset = InstanceSceneDataBuffers.InstanceHierarchyOffset;
InstanceUploadInfo.InstancePayloadExtension = InstanceSceneDataBuffers.InstancePayloadExtension;
InstanceUploadInfo.InstanceLocalBounds = InstanceSceneDataBuffers.InstanceLocalBounds;
#if WITH_EDITOR
InstanceUploadInfo.InstanceEditorData = InstanceSceneDataBuffers.InstanceEditorData;
#endif
(1)
UploadDataSourceAdapter cpu 信息获取读写封装
PrimitiveUploader gpu 数据读写封装
Source\Runtime\Renderer\Private\GPUScene.cpp
ParallelForTemplate(TEXT("GPUScene Upload Primitives Task"), TaskContext.NumPrimitiveDataUploads, 1, [&TaskContext, &UploadDataSourceAdapter](int32 ItemIndex)
{
FOptionalTaskTagScope TaskTagScope(ETaskTag::EParallelRenderingThread);
FVector4f* DstData = static_cast<FVector4f*>(TaskContext.PrimitiveUploader->GetRef(ItemIndex));
UploadDataSourceAdapter.GetPrimitiveShaderData(ItemIndex, DstData);
}, bExecuteInParallel ? EParallelForFlags::None : EParallelForFlags::ForceSingleThread);
}