From 86a2067b4936b1abfbf87ced4de8e83c4578900b Mon Sep 17 00:00:00 2001
From: FishOrBear <cay776@gmail.com>
Date: Thu, 1 Jul 2021 11:03:50 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BC=95=E6=93=8E=E4=BB=A5?=
 =?UTF-8?q?=E4=BE=BF=E6=94=AF=E6=8C=81=E8=BF=90=E8=A1=8C=E6=97=B6=E6=9E=84?=
 =?UTF-8?q?=E5=BB=BA=E8=B7=9D=E7=A6=BB=E5=9C=BA=E9=98=B4=E5=BD=B1=E5=92=8C?=
 =?UTF-8?q?MeshCard?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Engine/Classes/Engine/StaticMesh.h        |   4 +-
 .../Runtime/Engine/Private/StaticMesh.cpp     |  11 +-
 .../Engine/Public/DerivedMeshDataTaskUtils.h  |   4 +-
 .../Engine/Public/MeshCardRepresentation.h    |  18 ++--
 .../Engine/Public/ObjectCacheContext.h        |  12 +--
 .../Engine/Public/StaticMeshResources.h       | 100 +++++++++---------
 .../Private/DistanceFieldStreaming.cpp        |  11 ++
 7 files changed, 86 insertions(+), 74 deletions(-)

diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/StaticMesh.h b/Engine/Source/Runtime/Engine/Classes/Engine/StaticMesh.h
index 54259bf..769277b 100644
--- a/Engine/Source/Runtime/Engine/Classes/Engine/StaticMesh.h
+++ b/Engine/Source/Runtime/Engine/Classes/Engine/StaticMesh.h
@@ -1377,7 +1377,7 @@ public:
 	/**
 	 * Builds static mesh render buffers from a list of MeshDescriptions, one per LOD.
 	 */
-	ENGINE_API bool BuildFromMeshDescriptions(const TArray<const FMeshDescription*>& MeshDescriptions, const FBuildMeshDescriptionsParams& Params = FBuildMeshDescriptionsParams());
+	ENGINE_API bool BuildFromMeshDescriptions(const TArray<const FMeshDescription*>& MeshDescriptions, const FBuildMeshDescriptionsParams& Params = FBuildMeshDescriptionsParams(), bool InNeedsCPUAccess = false);
 	
 	/** Builds a LOD resource from a MeshDescription */
 	ENGINE_API void BuildFromMeshDescription(const FMeshDescription& MeshDescription, FStaticMeshLODResources& LODResources);
@@ -1861,4 +1861,4 @@ class FStaticMeshBuildContext : public FStaticMeshCompilationContext
 {
 public:
 	bool bHasRenderDataChanged = false;
-};
\ No newline at end of file
+};
diff --git a/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp b/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp
index 8d00c60..330c7f5 100644
--- a/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp
+++ b/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp
@@ -1154,7 +1154,7 @@ void FStaticMeshVertexBuffers::InitFromDynamicVertex(FLocalVertexFactory* Vertex
 		});
 };
 
-FStaticMeshLODResources::FStaticMeshLODResources(bool bAddRef)
+FStaticMeshLODResources::FStaticMeshLODResources(bool bAddRef, bool InNeedsCPUAccess)
 	: CardRepresentationData(nullptr)
 	, MaxDeviation(0.0f)
 	, bHasDepthOnlyIndices(false)
@@ -1170,6 +1170,7 @@ FStaticMeshLODResources::FStaticMeshLODResources(bool bAddRef)
 #if STATS
 	, StaticMeshIndexMemory(0)
 #endif
+	, IndexBuffer(InNeedsCPUAccess)
 {
 	if (bAddRef)
 	{
@@ -1744,14 +1745,14 @@ void FStaticMeshRenderData::ReleaseResources()
 	NaniteResources.ReleaseResources();
 }
 
-void FStaticMeshRenderData::AllocateLODResources(int32 NumLODs)
+void FStaticMeshRenderData::AllocateLODResources(int32 NumLODs, bool InNeedsCPUAccess)
 {
 	check(LODResources.Num() == 0);
 	LODResources.Reserve(NumLODs);
 	LODVertexFactories.Reserve(NumLODs);
 	while (LODResources.Num() < NumLODs)
 	{
-		LODResources.Add(new FStaticMeshLODResources);
+		LODResources.Add(new FStaticMeshLODResources(true, InNeedsCPUAccess));
 		new (LODVertexFactories) FStaticMeshVertexFactories(GMaxRHIFeatureLevel);
 	}
 }
@@ -5729,7 +5730,7 @@ void UStaticMesh::BuildFromStaticMeshDescriptions(const TArray<UStaticMeshDescri
 }
 
 
-bool UStaticMesh::BuildFromMeshDescriptions(const TArray<const FMeshDescription*>& MeshDescriptions, const FBuildMeshDescriptionsParams& Params)
+bool UStaticMesh::BuildFromMeshDescriptions(const TArray<const FMeshDescription*>& MeshDescriptions, const FBuildMeshDescriptionsParams& Params, bool InNeedsCPUAccess)
 {
 	// Set up
 	NeverStream = true;
@@ -5775,7 +5776,7 @@ bool UStaticMesh::BuildFromMeshDescriptions(const TArray<const FMeshDescription*
 	#endif
 
 	SetRenderData(MakeUnique<FStaticMeshRenderData>());
-	GetRenderData()->AllocateLODResources(MeshDescriptions.Num());
+	GetRenderData()->AllocateLODResources(MeshDescriptions.Num(), InNeedsCPUAccess);
 
 	// Build render data from each mesh description
 
diff --git a/Engine/Source/Runtime/Engine/Public/DerivedMeshDataTaskUtils.h b/Engine/Source/Runtime/Engine/Public/DerivedMeshDataTaskUtils.h
index c10353b..1145a58 100644
--- a/Engine/Source/Runtime/Engine/Public/DerivedMeshDataTaskUtils.h
+++ b/Engine/Source/Runtime/Engine/Public/DerivedMeshDataTaskUtils.h
@@ -10,7 +10,7 @@
 #include "StaticMeshResources.h"
 
 /** Source mesh data. Valid only in specific cases, when StaticMesh doesn't contain original data anymore (e.g. it's replaced by the Nanite coarse mesh representation) */
-class FSourceMeshDataForDerivedDataTask
+class ENGINE_API FSourceMeshDataForDerivedDataTask
 {
 public:
 	TArray<uint32> TriangleIndices;
@@ -30,4 +30,4 @@ public:
 	{ 
 		return TriangleIndices.Num() > 0;
 	}
-};
\ No newline at end of file
+};
diff --git a/Engine/Source/Runtime/Engine/Public/MeshCardRepresentation.h b/Engine/Source/Runtime/Engine/Public/MeshCardRepresentation.h
index 1e1ec80..074373e 100644
--- a/Engine/Source/Runtime/Engine/Public/MeshCardRepresentation.h
+++ b/Engine/Source/Runtime/Engine/Public/MeshCardRepresentation.h
@@ -9,9 +9,9 @@
 #include "CoreMinimal.h"
 #include "Containers/LockFreeList.h"
 #include "ProfilingDebugging/ResourceSize.h"
-#include "Engine/EngineTypes.h"
+// #include "Engine/EngineTypes.h"
 #include "UObject/GCObject.h"
-#include "RenderResource.h"
+// #include "RenderResource.h"
 #include "RenderingThread.h"
 #include "Templates/UniquePtr.h"
 #include "DerivedMeshDataTaskUtils.h"
@@ -20,7 +20,7 @@
 template <class T> class TLockFreePointerListLIFO;
 class FSignedDistanceFieldBuildMaterialData;
 
-class FLumenCardBuildData
+class ENGINE_API FLumenCardBuildData
 {
 public:
 	FVector Center;
@@ -57,7 +57,7 @@ public:
 	}
 };
 
-class FLumenCardBuildDebugPoint
+class ENGINE_API FLumenCardBuildDebugPoint
 {
 public:
 	FVector Origin;
@@ -65,7 +65,7 @@ public:
 	bool bValid;
 };
 
-class FLumenCardBuildDebugLine
+class ENGINE_API FLumenCardBuildDebugLine
 {
 public:
 	FVector Origin;
@@ -73,7 +73,7 @@ public:
 	int32 Orientation;
 };
 
-class FMeshCardsBuildData
+class ENGINE_API FMeshCardsBuildData
 {
 public:
 	FBox Bounds;
@@ -95,7 +95,7 @@ public:
 };
 
 // Unique id per card representation data instance.
-class FCardRepresentationDataId
+class ENGINE_API FCardRepresentationDataId
 {
 public:
 	uint32 Value = 0;
@@ -117,7 +117,7 @@ public:
 };
 
 /** Card representation payload and output of the mesh build process. */
-class FCardRepresentationData : public FDeferredCleanupInterface
+class ENGINE_API FCardRepresentationData : public FDeferredCleanupInterface
 {
 public:
 
@@ -276,4 +276,4 @@ extern ENGINE_API FCardRepresentationAsyncQueue* GCardRepresentationAsyncQueue;
 
 extern ENGINE_API FString BuildCardRepresentationDerivedDataKey(const FString& InMeshKey);
 
-extern ENGINE_API void BeginCacheMeshCardRepresentation(const ITargetPlatform* TargetPlatform, UStaticMesh* StaticMeshAsset, class FStaticMeshRenderData& RenderData, const FString& DistanceFieldKey, FSourceMeshDataForDerivedDataTask* OptionalSourceMeshData);
\ No newline at end of file
+extern ENGINE_API void BeginCacheMeshCardRepresentation(const ITargetPlatform* TargetPlatform, UStaticMesh* StaticMeshAsset, class FStaticMeshRenderData& RenderData, const FString& DistanceFieldKey, FSourceMeshDataForDerivedDataTask* OptionalSourceMeshData);
diff --git a/Engine/Source/Runtime/Engine/Public/ObjectCacheContext.h b/Engine/Source/Runtime/Engine/Public/ObjectCacheContext.h
index 16e2ef1..0963fb9 100644
--- a/Engine/Source/Runtime/Engine/Public/ObjectCacheContext.h
+++ b/Engine/Source/Runtime/Engine/Public/ObjectCacheContext.h
@@ -21,7 +21,7 @@ class USkeletalMesh;
  *  Class to abstract implementation details of the containers used inside the
  *  object cache so they can be changed later if needed without API changes.
  */
-template< class T > class TObjectCacheIterator
+template< class T > class ENGINE_API TObjectCacheIterator
 {
 public:
 	/**
@@ -62,7 +62,7 @@ protected:
  *  reverse lookup tables that can be used during heavy scene updates
  *  of async asset compilation.
  */
-class FObjectCacheContext
+class ENGINE_API FObjectCacheContext
 {
 public:
 	TObjectCacheIterator<UPrimitiveComponent>   GetPrimitiveComponents();
@@ -95,12 +95,12 @@ private:
  * is destroyed. Should only be used during short periods when there is no new
  * objects created and no object dependency changes. (i.e. Scene update after asset compilation).
  */
-class FObjectCacheContextScope
+class ENGINE_API FObjectCacheContextScope
 {
 public:
-	ENGINE_API FObjectCacheContextScope();
-	ENGINE_API ~FObjectCacheContextScope();
-	ENGINE_API FObjectCacheContext& GetContext();
+	FObjectCacheContextScope();
+	~FObjectCacheContextScope();
+	FObjectCacheContext& GetContext();
 private:
 	// Scopes can be stacked over one another, but only the outermost will
 	// own the actual context and destroy it at the end, all inner scopes
diff --git a/Engine/Source/Runtime/Engine/Public/StaticMeshResources.h b/Engine/Source/Runtime/Engine/Public/StaticMeshResources.h
index 29c41f6..040e72d 100644
--- a/Engine/Source/Runtime/Engine/Public/StaticMeshResources.h
+++ b/Engine/Source/Runtime/Engine/Public/StaticMeshResources.h
@@ -349,12 +349,12 @@ struct TIsContiguousContainer<FStaticMeshSectionArray> : TIsContiguousContainer<
 };
 //using FStaticMeshSectionArray = TArray<FStaticMeshSection, TInlineAllocator<1>>;
 
-/** 
+/**
  * Rendering resources needed to render an individual static mesh LOD.
  * This structure is ref counted to allow the LOD streamer to evaluate the number of readers to it (readers that could access the CPU data).
  * Because the stream out clears the CPU readable data, CPU code that samples it must ensure to only reference LODs above CurrentFirstLODIdx.
  */
-struct FStaticMeshLODResources : public FRefCountBase
+struct ENGINE_API FStaticMeshLODResources : public FRefCountBase
 {
 public:
 
@@ -362,7 +362,7 @@ public:
 	FStaticMeshSectionArray Sections;
 
 	/** Distance field data associated with this mesh, null if not present.  */
-	class FDistanceFieldVolumeData* DistanceFieldData = nullptr; 
+	class FDistanceFieldVolumeData* DistanceFieldData = nullptr;
 
 	/** Card Representation data associated with this mesh, null if not present.  */
 	class FCardRepresentationData* CardRepresentationData;
@@ -431,11 +431,11 @@ public:
 	FStaticMeshSectionAreaWeightedTriangleSamplerArray AreaWeightedSectionSamplers;
 	/** Allows uniform random selection of triangles on GPU. It is not cooked and serialised but created at runtime from AreaWeightedSectionSamplers when it is available and static mesh bSupportGpuUniformlyDistributedSampling=true*/
 	FStaticMeshSectionAreaWeightedTriangleSamplerBuffer AreaWeightedSectionSamplersBuffer;
-	
+
 	/** Default constructor. Add a reference if not stored with a TRefCountPtr */
-	ENGINE_API FStaticMeshLODResources(bool bAddRef = true);
+	FStaticMeshLODResources(bool bAddRef = true, bool InNeedsCPUAccess = false);
 
-	ENGINE_API ~FStaticMeshLODResources();
+	~FStaticMeshLODResources();
 
 	template <typename TBatcher>
 	void ReleaseRHIForStreaming(TBatcher& Batcher)
@@ -467,12 +467,12 @@ public:
 	void GetResourceSizeEx(FResourceSizeEx& CumulativeResourceSize) const;
 
 	/** Return the triangle count of this LOD. */
-	ENGINE_API int32 GetNumTriangles() const;
+	int32 GetNumTriangles() const;
 
 	/** Return the number of vertices in this LOD. */
-	ENGINE_API int32 GetNumVertices() const;
+	int32 GetNumVertices() const;
 
-	ENGINE_API int32 GetNumTexCoords() const;
+	int32 GetNumTexCoords() const;
 
 private:
 	enum EClassDataStripFlag : uint8
@@ -610,13 +610,13 @@ using FStaticMeshVertexFactoriesArray = TArray<FStaticMeshVertexFactories>;
 /**
  * FStaticMeshRenderData - All data needed to render a static mesh.
  */
-class FStaticMeshRenderData
+class ENGINE_API FStaticMeshRenderData
 {
 public:
 
 	/** Default constructor. */
-	ENGINE_API FStaticMeshRenderData();
-	ENGINE_API ~FStaticMeshRenderData();
+	 FStaticMeshRenderData();
+	 ~FStaticMeshRenderData();
 
 	/**
 	 * Per-LOD resources. For compatibility reasons, the FStaticMeshLODResources array are not referenced through TRefCountPtr.
@@ -672,7 +672,7 @@ public:
 	 * Cache derived renderable data for the static mesh with the provided
 	 * level of detail settings.
 	 */
-	ENGINE_API void Cache(const ITargetPlatform* TargetPlatform, UStaticMesh* Owner, const FStaticMeshLODSettings& LODSettings);
+	 void Cache(const ITargetPlatform* TargetPlatform, UStaticMesh* Owner, const FStaticMeshLODSettings& LODSettings);
 #endif // #if WITH_EDITORONLY_DATA
 
 	/** Count the number of LODs that are inlined and not streamable. Starting from the last LOD and stopping at the first non inlined LOD. */
@@ -690,13 +690,13 @@ public:
 	void InitResources(ERHIFeatureLevel::Type InFeatureLevel, UStaticMesh* Owner);
 
 	/** Releases the render resources. */
-	ENGINE_API void ReleaseResources();
+	 void ReleaseResources();
 
 	/** Compute the size of this resource. */
 	void GetResourceSizeEx(FResourceSizeEx& CumulativeResourceSize) const;
 
 	/** Allocate LOD resources. */
-	ENGINE_API void AllocateLODResources(int32 NumLODs);
+	 void AllocateLODResources(int32 NumLODs, bool InNeedsCPUAccess = false);
 
 	/** Update LOD-SECTION uv densities. */
 	void ComputeUVDensities();
@@ -705,11 +705,11 @@ public:
 
 #if WITH_EDITOR
 	/** Resolve all per-section settings. */
-	ENGINE_API void ResolveSectionInfo(UStaticMesh* Owner);
+	 void ResolveSectionInfo(UStaticMesh* Owner);
 #endif // #if WITH_EDITORONLY_DATA
 
 	/** Return first valid LOD index starting at MinLODIdx. */
-	ENGINE_API int32 GetFirstValidLODIdx(int32 MinLODIdx) const;
+	 int32 GetFirstValidLODIdx(int32 MinLODIdx) const;
 
 	/** Return the current first LODIdx that can be used. */
 	FORCEINLINE int32 GetCurrentFirstLODIdx(int32 MinLODIdx) const
@@ -717,9 +717,9 @@ public:
 		return GetFirstValidLODIdx(FMath::Max<int32>(CurrentFirstLODIdx, MinLODIdx));
 	}
 
-	/** 
+	/**
 	 * Return the current first LOD that can be used for rendering starting at MinLODIdx.
-	 * This takes into account the streaming status from CurrentFirstLODIdx, 
+	 * This takes into account the streaming status from CurrentFirstLODIdx,
 	 * and MinLODIdx is expected to be UStaticMesh::MinLOD, which is platform specific.
 	 */
 	FORCEINLINE const FStaticMeshLODResources* GetCurrentFirstLOD(int32 MinLODIdx) const
@@ -755,7 +755,7 @@ public:
 };
 
 /**
- * FStaticMeshComponentRecreateRenderStateContext - Destroys render state for all StaticMeshComponents using a given StaticMesh and 
+ * FStaticMeshComponentRecreateRenderStateContext - Destroys render state for all StaticMeshComponents using a given StaticMesh and
  * recreates them when it goes out of scope. Used to ensure stale rendering data isn't kept around in the components when importing
  * over or rebuilding an existing static mesh.
  */
@@ -895,10 +895,10 @@ public:
 
 	/** Sets up a FMeshBatch for a specific LOD and element. */
 	virtual bool GetMeshElement(
-		int32 LODIndex, 
-		int32 BatchIndex, 
-		int32 ElementIndex, 
-		uint8 InDepthPriorityGroup, 
+		int32 LODIndex,
+		int32 BatchIndex,
+		int32 ElementIndex,
+		uint8 InDepthPriorityGroup,
 		bool bUseSelectionOutline,
 		bool bAllowPreCulledIndices,
 		FMeshBatch& OutMeshBatch) const;
@@ -982,8 +982,8 @@ public:
 #if RHI_RAYTRACING
 	virtual void GetDynamicRayTracingInstances(FRayTracingMaterialGatheringContext& Context, TArray<FRayTracingInstance>& OutRayTracingInstances) override;
 	virtual bool IsRayTracingRelevant() const override { return true; }
-	virtual bool IsRayTracingStaticRelevant() const override 
-	{ 
+	virtual bool IsRayTracingStaticRelevant() const override
+	{
 		const bool bAllowStaticLighting = FReadOnlyCVARCache::Get().bAllowStaticLighting;
 		const bool bIsStaticInstance = !bDynamicRayTracingGeometry;
 		return bIsStaticInstance && !HasViewDependentDPG() && !(bAllowStaticLighting && HasStaticLighting() && !HasValidSettingsForStaticLighting());
@@ -1073,8 +1073,8 @@ protected:
 
 	TArray<FLODInfo> LODs;
 
-	const FDistanceFieldVolumeData* DistanceFieldData;	
-	const FCardRepresentationData* CardRepresentationData;	
+	const FDistanceFieldVolumeData* DistanceFieldData;
+	const FCardRepresentationData* CardRepresentationData;
 
 #if RHI_RAYTRACING
 	bool bSupportRayTracing;
@@ -1233,7 +1233,7 @@ public:
 	}
 
 	void Serialize(FArchive& Ar);
-	
+
 	void AllocateInstances(int32 InNumInstances, int32 InNumCustomDataFloats, EResizeBufferFlags BufferFlags, bool DestroyExistingInstances)
 	{
 		NumInstances = InNumInstances;
@@ -1300,7 +1300,7 @@ public:
 		Transform.M[3][0] = Origin.X;
 		Transform.M[3][1] = Origin.Y;
 		Transform.M[3][2] = Origin.Z;
-#if 1 
+#if 1
 		// GPUCULL_TODO: This causes problems when using this as a normal real proper matrix and concatenating!
 		Transform.M[3][3] = 0.f;
 #else
@@ -1354,7 +1354,7 @@ public:
 			SetInstanceCustomDataInternal(InstanceIndex, i, 0);
 		}
 	}
-	
+
 	FORCEINLINE_DEBUGGABLE void SetInstance(int32 InstanceIndex, const FMatrix& Transform, float RandomInstanceID, const FVector2D& LightmapUVBias, const FVector2D& ShadowmapUVBias)
 	{
 		FVector4 Origin(Transform.M[3][0], Transform.M[3][1], Transform.M[3][2], RandomInstanceID);
@@ -1416,12 +1416,12 @@ public:
 	{
 		SetInstanceLightMapDataInternal(InstanceIndex, FVector4(LightmapUVBias.X, LightmapUVBias.Y, ShadowmapUVBias.X, ShadowmapUVBias.Y));
 	}
-	
+
 	FORCEINLINE void SetInstanceCustomData(int32 InstanceIndex, int32 Index, float CustomData)
 	{
 		SetInstanceCustomDataInternal(InstanceIndex, Index, CustomData);
 	}
-	
+
 	FORCEINLINE_DEBUGGABLE void NullifyInstance(int32 InstanceIndex)
 	{
 		SetInstanceOriginInternal(InstanceIndex, FVector4(0, 0, 0, 0));
@@ -1513,7 +1513,7 @@ public:
 			check((void*)((&ElementData[Index1]) + 0) >= (void*)(InstanceTransformDataPtr));
 			check((void*)((&ElementData[Index2]) + 1) <= (void*)(InstanceTransformDataPtr + CurrentSize));
 			check((void*)((&ElementData[Index2]) + 0) >= (void*)(InstanceTransformDataPtr));
-			
+
 			FInstanceTransformMatrix<float> TempStore = ElementData[Index1];
 			ElementData[Index1] = ElementData[Index2];
 			ElementData[Index2] = TempStore;
@@ -1538,7 +1538,7 @@ public:
 			check((void*)((&ElementData[Index1]) + 0) >= (void*)(InstanceLightmapDataPtr));
 			check((void*)((&ElementData[Index2]) + 1) <= (void*)(InstanceLightmapDataPtr + CurrentSize));
 			check((void*)((&ElementData[Index2]) + 0) >= (void*)(InstanceLightmapDataPtr));
-			
+
 			FInstanceLightMapVector TempStore = ElementData[Index1];
 			ElementData[Index1] = ElementData[Index2];
 			ElementData[Index2] = TempStore;
@@ -1641,8 +1641,8 @@ public:
 
 	FORCEINLINE_DEBUGGABLE SIZE_T GetResourceSize() const
 	{
-		return	InstanceOriginData->GetResourceSize() + 
-				InstanceTransformData->GetResourceSize() + 
+		return	InstanceOriginData->GetResourceSize() +
+				InstanceTransformData->GetResourceSize() +
 				InstanceLightmapData->GetResourceSize() +
 				InstanceCustomData->GetResourceSize();
 	}
@@ -1655,17 +1655,17 @@ private:
 		uint32 CurrentSize = InstanceTransformData->Num() * InstanceTransformData->GetStride();
 		check((void*)((&ElementData[InstanceIndex]) + 1) <= (void*)(InstanceTransformDataPtr + CurrentSize));
 		check((void*)((&ElementData[InstanceIndex]) + 0) >= (void*)(InstanceTransformDataPtr));
-		
+
 		Transform[0][0] = ElementData[InstanceIndex].InstanceTransform1[0];
 		Transform[0][1] = ElementData[InstanceIndex].InstanceTransform1[1];
 		Transform[0][2] = ElementData[InstanceIndex].InstanceTransform1[2];
 		Transform[0][3] = ElementData[InstanceIndex].InstanceTransform1[3];
-		
+
 		Transform[1][0] = ElementData[InstanceIndex].InstanceTransform2[0];
 		Transform[1][1] = ElementData[InstanceIndex].InstanceTransform2[1];
 		Transform[1][2] = ElementData[InstanceIndex].InstanceTransform2[2];
 		Transform[1][3] = ElementData[InstanceIndex].InstanceTransform2[3];
-		
+
 		Transform[2][0] = ElementData[InstanceIndex].InstanceTransform3[0];
 		Transform[2][1] = ElementData[InstanceIndex].InstanceTransform3[1];
 		Transform[2][2] = ElementData[InstanceIndex].InstanceTransform3[2];
@@ -1691,7 +1691,7 @@ private:
 
 		LightmapData = FVector4
 		(
-			float(ElementData[InstanceIndex].InstanceLightmapAndShadowMapUVBias[0]) / 32767.0f, 
+			float(ElementData[InstanceIndex].InstanceLightmapAndShadowMapUVBias[0]) / 32767.0f,
 			float(ElementData[InstanceIndex].InstanceLightmapAndShadowMapUVBias[1]) / 32767.0f,
 			float(ElementData[InstanceIndex].InstanceLightmapAndShadowMapUVBias[2]) / 32767.0f,
 			float(ElementData[InstanceIndex].InstanceLightmapAndShadowMapUVBias[3]) / 32767.0f
@@ -1708,7 +1708,7 @@ private:
 		for (int32 i = 0; i < NumCustomDataFloats; ++i)
 		{
 			int32 CustomDataIndex = NumCustomDataFloats * InstanceIndex + i;
-			
+
 			check((void*)((&ElementData[CustomDataIndex]) + 1) <= (void*)(InstanceCustomDataPtr + CurrentSize));
 			check((void*)((&ElementData[CustomDataIndex]) + 0) >= (void*)(InstanceCustomDataPtr));
 
@@ -1785,16 +1785,16 @@ private:
 	{
 		delete InstanceOriginData;
 		InstanceOriginDataPtr = nullptr;
-		
+
 		delete InstanceTransformData;
 		InstanceTransformDataPtr = nullptr;
-		
+
 		delete InstanceLightmapData;
 		InstanceLightmapDataPtr = nullptr;
-		 		
+
 		delete InstanceCustomData;
 		InstanceCustomData = nullptr;
-		 		
+
 		InstanceOriginData = new TStaticMeshVertexData<FVector4>();
 		InstanceOriginData->ResizeBuffer(InNumInstances, BufferFlags);
 		InstanceLightmapData = new TStaticMeshVertexData<FInstanceLightMapVector>();
@@ -1808,7 +1808,7 @@ private:
 			InstanceTransformData = new TStaticMeshVertexData<FInstanceTransformMatrix<float>>();
 		}
 		InstanceTransformData->ResizeBuffer(InNumInstances, BufferFlags);
-		
+
 		InstanceCustomData = new TStaticMeshVertexData<float>();
 		InstanceCustomData->ResizeBuffer(NumCustomDataFloats * InNumInstances, BufferFlags);
 	}
@@ -1820,7 +1820,7 @@ private:
 	uint8* InstanceTransformDataPtr = nullptr;
 
 	FStaticMeshVertexDataInterface* InstanceLightmapData = nullptr;
-	uint8* InstanceLightmapDataPtr = nullptr;	
+	uint8* InstanceLightmapDataPtr = nullptr;
 
 	FStaticMeshVertexDataInterface* InstanceCustomData = nullptr;
 	uint8* InstanceCustomDataPtr = nullptr;
@@ -1829,7 +1829,7 @@ private:
 	int32 NumCustomDataFloats = 0;
 	bool bUseHalfFloat = false;
 };
-	
+
 #if WITH_EDITOR
 /**
  * Remaps painted vertex colors when the renderable mesh has changed.
@@ -1844,7 +1844,7 @@ ENGINE_API void RemapPaintedVertexColors(
 	const FColorVertexBuffer* InOverrideColors,
 	const FPositionVertexBuffer& OldPositions,
 	const FStaticMeshVertexBuffer& OldVertexBuffer,
-	const FPositionVertexBuffer& NewPositions,	
+	const FPositionVertexBuffer& NewPositions,
 	const FStaticMeshVertexBuffer* OptionalVertexBuffer,
 	TArray<FColor>& OutOverrideColors
 	);
diff --git a/Engine/Source/Runtime/Renderer/Private/DistanceFieldStreaming.cpp b/Engine/Source/Runtime/Renderer/Private/DistanceFieldStreaming.cpp
index 384e77c..2b92ff9 100644
--- a/Engine/Source/Runtime/Renderer/Private/DistanceFieldStreaming.cpp
+++ b/Engine/Source/Runtime/Renderer/Private/DistanceFieldStreaming.cpp
@@ -334,6 +334,12 @@ void FDistanceFieldSceneData::AsyncUpdate(FDistanceFieldAsyncUpdateParameters Up
 			check(ReadRequest.BulkData->IsBulkDataLoaded() && ReadRequest.BulkData->GetBulkDataSize() > 0);
 			BulkDataReadPtr = (const uint8*)ReadRequest.BulkData->LockReadOnly() + ReadRequest.BulkOffset;
 		}
+#else
+		if (ReadRequest.BulkData && ReadRequest.BulkData->GetBulkDataFlags() == 1024)
+		{
+			check(ReadRequest.BulkData->IsBulkDataLoaded() && ReadRequest.BulkData->GetBulkDataSize() > 0);
+			BulkDataReadPtr = (const uint8*)ReadRequest.BulkData->LockReadOnly() + ReadRequest.BulkOffset;
+		}
 #endif
 		const int32 NumIndirectionEntries = MipBuiltData.IndirectionDimensions.X * MipBuiltData.IndirectionDimensions.Y * MipBuiltData.IndirectionDimensions.Z;
 		const uint32 ExpectedBulkSize = NumIndirectionEntries * sizeof(uint32) + ReadRequest.NumDistanceFieldBricks * BrickSizeBytes;
@@ -386,6 +392,11 @@ void FDistanceFieldSceneData::AsyncUpdate(FDistanceFieldAsyncUpdateParameters Up
 		{
 			ReadRequest.BulkData->Unlock();
 		}
+#else
+		if (ReadRequest.BulkData && ReadRequest.BulkData->GetBulkDataFlags() == 1024)
+		{
+			ReadRequest.BulkData->Unlock();
+		}
 #endif
 
 		BrickUploadIndex += MipState.NumBricks;
-- 
2.32.0.windows.1

