예제 #1
0
void FDrawEvent::Start(FRHICommandList& InRHICmdList, const FColor& Color, const TCHAR* Fmt, ...)
{
	check(IsInParallelRenderingThread() || IsInRHIThread());
	{
		va_list ptr;
		va_start(ptr, Fmt);
		TCHAR TempStr[256];
		// Build the string in the temp buffer
		FCString::GetVarArgs(TempStr, ARRAY_COUNT(TempStr), ARRAY_COUNT(TempStr) - 1, Fmt, ptr);
		InRHICmdList.PushEvent(TempStr);
		RHICmdList = &InRHICmdList;
	}
}
예제 #2
0
void FDrawEventRHIExecute::Start(IRHIComputeContext& InRHICommandContext, FColor Color, const TCHAR* Fmt, ...)
{
	check(IsInParallelRenderingThread() || IsInRHIThread() || (!GRHIThread && IsInRenderingThread()));
	{
		va_list ptr;
		va_start(ptr, Fmt);
		TCHAR TempStr[256];
		// Build the string in the temp buffer
		FCString::GetVarArgs(TempStr, ARRAY_COUNT(TempStr), ARRAY_COUNT(TempStr) - 1, Fmt, ptr);
		RHICommandContext = &InRHICommandContext;
		RHICommandContext->RHIPushEvent(TempStr, Color);
	}
}
예제 #3
0
FPrimitiveViewRelevance FPaperBatchSceneProxy::GetViewRelevance(const FSceneView* View)
{
	checkSlow(IsInParallelRenderingThread());

	FPrimitiveViewRelevance Result;
	Result.bDrawRelevance = IsShown(View) && View->Family->EngineShowFlags.Paper2DSprites;
	Result.bRenderCustomDepth = ShouldRenderCustomDepth();
	Result.bRenderInMainPass = ShouldRenderInMainPass();

	Result.bMaskedRelevance = true;
	//Result.bNormalTranslucencyRelevance = true;
	Result.bDynamicRelevance = true;
	Result.bOpaqueRelevance = true;

	return Result;
}
예제 #4
0
bool FVelocityDrawingPolicy::HasVelocity(const FViewInfo& View, const FPrimitiveSceneInfo* PrimitiveSceneInfo)
{
	checkSlow(IsInParallelRenderingThread());

	// No velocity if motionblur is off, or if it's a non-moving object (treat as background in that case)
	if (View.bCameraCut || !PrimitiveSceneInfo->Proxy->IsMovable())
	{
		return false;
	}

	if (PrimitiveSceneInfo->Proxy->AlwaysHasVelocity())
	{
		return true;
	}

	if (PrimitiveSceneInfo->bVelocityIsSupressed)
	{
		return false;
	}

	// check if the primitive has moved
	{
		FMatrix PreviousLocalToWorld;

		// hack
		FScene* Scene = PrimitiveSceneInfo->Scene;

		if (Scene->MotionBlurInfoData.GetPrimitiveMotionBlurInfo(PrimitiveSceneInfo, PreviousLocalToWorld))
		{
			check(PrimitiveSceneInfo->Proxy);

			const FMatrix& LocalToWorld = PrimitiveSceneInfo->Proxy->GetLocalToWorld();

			// Hasn't moved (treat as background by not rendering any special velocities)?
			if (LocalToWorld.Equals(PreviousLocalToWorld, 0.0001f))
			{
				return false;
			}
		}
		else 
		{
			return false;
		}
	}

	return true;
}
예제 #5
0
void FRenderResource::InitResourceFromPossiblyParallelRendering()
{
	if (IsInRenderingThread())
	{
		InitResource();
	}
	else
	{
		check(IsInParallelRenderingThread());
		class FInitResourceRenderThreadTask
		{
			FRenderResource& Resource;
			FScopedEvent& Event;
		public:

			FInitResourceRenderThreadTask(FRenderResource& InResource, FScopedEvent& InEvent)
				: Resource(InResource)
				, Event(InEvent)
			{
			}

			FORCEINLINE TStatId GetStatId() const
			{
				RETURN_QUICK_DECLARE_CYCLE_STAT(FInitResourceRenderThreadTask, STATGROUP_TaskGraphTasks);
			}

			ENamedThreads::Type GetDesiredThread()
			{
				return ENamedThreads::RenderThread_Local;
			}

			static ESubsequentsMode::Type GetSubsequentsMode() { return ESubsequentsMode::FireAndForget; }

			void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent)
			{
				Resource.InitResource();
				Event.Trigger();
			}
		};
		{
			FScopedEvent Event;
			TGraphTask<FInitResourceRenderThreadTask>::CreateTask().ConstructAndDispatchWhenReady(*this, Event);
		}
	}
}
예제 #6
0
bool FVelocityDrawingPolicy::HasVelocityOnBasePass(const FViewInfo& View,const FPrimitiveSceneProxy* PrimitiveSceneProxy, const FPrimitiveSceneInfo* PrimitiveSceneInfo, const FMeshBatch& Mesh, bool& bOutHasTransform, FMatrix& OutTransform)
{
	checkSlow(IsInParallelRenderingThread());
	// No velocity if motionblur is off, or if it's a non-moving object (treat as background in that case)
	if (View.bCameraCut)
	{
		return false;
	}

	//@todo-rco: Where is this set?
	if (PrimitiveSceneInfo->bVelocityIsSupressed)
	{
		return false;
	}

	// hack
	FScene* Scene = PrimitiveSceneInfo->Scene;
	if (Scene->MotionBlurInfoData.GetPrimitiveMotionBlurInfo(PrimitiveSceneInfo, OutTransform))
	{
		bOutHasTransform = true;
/*
		const FMatrix& LocalToWorld = PrimitiveSceneProxy->GetLocalToWorld();
		// Hasn't moved (treat as background by not rendering any special velocities)?
		if (LocalToWorld.Equals(OutTransform, 0.0001f))
		{
			return false;
		}
*/
		return true;
	}

	bOutHasTransform = false;
	if (PrimitiveSceneProxy->IsMovable())
	{
		return true;
	}

	//@todo-rco: Optimize finding WPO!
	auto* Material = Mesh.MaterialRenderProxy->GetMaterial(Scene->GetFeatureLevel());
	return Material->MaterialModifiesMeshPosition_RenderThread() && Material->OutputsVelocityOnBasePass();
}
FUniformBufferRHIRef FUniformExpressionSet::CreateUniformBuffer(const FMaterialRenderContext& MaterialRenderContext, FRHICommandList* CommandListIfLocalMode, struct FLocalUniformBuffer* OutLocalUniformBuffer) const
{
	check(UniformBufferStruct);
	check(IsInParallelRenderingThread());
	
	FUniformBufferRHIRef UniformBuffer;

	if (UniformBufferStruct->GetSize() > 0)
	{
		FMemMark Mark(FMemStack::Get());
		void* const TempBuffer = FMemStack::Get().PushBytes(UniformBufferStruct->GetSize(),UNIFORM_BUFFER_STRUCT_ALIGNMENT);

		FLinearColor* TempVectorBuffer = (FLinearColor*)TempBuffer;
		for(int32 VectorIndex = 0;VectorIndex < UniformVectorExpressions.Num();++VectorIndex)
		{
			TempVectorBuffer[VectorIndex] = FLinearColor(0,0,0,0);
			UniformVectorExpressions[VectorIndex]->GetNumberValue(MaterialRenderContext,TempVectorBuffer[VectorIndex]);
		}

		float* TempScalarBuffer = (float*)(TempVectorBuffer + UniformVectorExpressions.Num());
		for(int32 ScalarIndex = 0;ScalarIndex < UniformScalarExpressions.Num();++ScalarIndex)
		{
			FLinearColor VectorValue(0,0,0,0);
			UniformScalarExpressions[ScalarIndex]->GetNumberValue(MaterialRenderContext,VectorValue);
			TempScalarBuffer[ScalarIndex] = VectorValue.R;
		}

		void** ResourceTable = (void**)((uint8*)TempBuffer + UniformBufferStruct->GetLayout().ResourceOffset);
		check(((UPTRINT)ResourceTable & 0x7) == 0);

		check(UniformBufferStruct->GetLayout().Resources.Num() == Uniform2DTextureExpressions.Num() * 2 + UniformCubeTextureExpressions.Num() * 2 + 2);

		// Cache 2D texture uniform expressions.
		for(int32 ExpressionIndex = 0;ExpressionIndex < Uniform2DTextureExpressions.Num();ExpressionIndex++)
		{
			const UTexture* Value;
			ESamplerSourceMode SourceMode;
			Uniform2DTextureExpressions[ExpressionIndex]->GetTextureValue(MaterialRenderContext,MaterialRenderContext.Material,Value,SourceMode);
			if (Value && Value->Resource)
			{
				//@todo-rco: Help track down a invalid values
				checkf(Value->IsA(UTexture::StaticClass()), TEXT("Expecting a UTexture! Value='%s' class='%s'"), *Value->GetName(), *Value->GetClass()->GetName());

				// UMaterial / UMaterialInstance should have caused all dependent textures to be PostLoaded, which initializes their rendering resource
				checkf(Value->TextureReference.TextureReferenceRHI, TEXT("Texture %s of class %s had invalid texture reference"), *Value->GetName(), *Value->GetClass()->GetName());

				*ResourceTable++ = Value->TextureReference.TextureReferenceRHI;
				FSamplerStateRHIRef* SamplerSource = &Value->Resource->SamplerStateRHI;

				if (SourceMode == SSM_Wrap_WorldGroupSettings)
				{
					SamplerSource = &Wrap_WorldGroupSettings->SamplerStateRHI;
				}
				else if (SourceMode == SSM_Clamp_WorldGroupSettings)
				{
					SamplerSource = &Clamp_WorldGroupSettings->SamplerStateRHI;
				}

				*ResourceTable++ = *SamplerSource;
			}
			else
			{
				*ResourceTable++ = GWhiteTexture->TextureRHI;
				*ResourceTable++ = GWhiteTexture->SamplerStateRHI;
			}
		}

		// Cache cube texture uniform expressions.
		for(int32 ExpressionIndex = 0;ExpressionIndex < UniformCubeTextureExpressions.Num();ExpressionIndex++)
		{
			const UTexture* Value;
			ESamplerSourceMode SourceMode;
			UniformCubeTextureExpressions[ExpressionIndex]->GetTextureValue(MaterialRenderContext,MaterialRenderContext.Material,Value,SourceMode);
			if(Value && Value->Resource)
			{
				check(Value->TextureReference.TextureReferenceRHI);
				*ResourceTable++ = Value->TextureReference.TextureReferenceRHI;
				FSamplerStateRHIRef* SamplerSource = &Value->Resource->SamplerStateRHI;

				if (SourceMode == SSM_Wrap_WorldGroupSettings)
				{
					SamplerSource = &Wrap_WorldGroupSettings->SamplerStateRHI;
				}
				else if (SourceMode == SSM_Clamp_WorldGroupSettings)
				{
					SamplerSource = &Clamp_WorldGroupSettings->SamplerStateRHI;
				}

				*ResourceTable++ = *SamplerSource;
			}
			else
			{
				*ResourceTable++ = GWhiteTexture->TextureRHI;
				*ResourceTable++ = GWhiteTexture->SamplerStateRHI;
			}
		}

		*ResourceTable++ = Wrap_WorldGroupSettings->SamplerStateRHI;
		*ResourceTable++ = Clamp_WorldGroupSettings->SamplerStateRHI;

		if (CommandListIfLocalMode)
		{
			check(OutLocalUniformBuffer);
			*OutLocalUniformBuffer = CommandListIfLocalMode->BuildLocalUniformBuffer(TempBuffer, UniformBufferStruct->GetSize(), UniformBufferStruct->GetLayout());
			check(OutLocalUniformBuffer->IsValid());
		}
		else
		{
			UniformBuffer = RHICreateUniformBuffer(TempBuffer, UniformBufferStruct->GetLayout(), UniformBuffer_MultiFrame);
			check(!OutLocalUniformBuffer->IsValid());
		}
	}

	return UniformBuffer;
}
FUniformBufferRHIRef FUniformExpressionSet::CreateUniformBuffer(const FMaterialRenderContext& MaterialRenderContext, FRHICommandList* CommandListIfLocalMode, struct FLocalUniformBuffer* OutLocalUniformBuffer) const
{
	check(UniformBufferStruct);
	check(IsInParallelRenderingThread());
	
	FUniformBufferRHIRef UniformBuffer;

	if (UniformBufferStruct->GetSize() > 0)
	{
		FMemMark Mark(FMemStack::Get());
		void* const TempBuffer = FMemStack::Get().PushBytes(UniformBufferStruct->GetSize(),UNIFORM_BUFFER_STRUCT_ALIGNMENT);

		FLinearColor* TempVectorBuffer = (FLinearColor*)TempBuffer;
		for(int32 VectorIndex = 0;VectorIndex < UniformVectorExpressions.Num();++VectorIndex)
		{
			TempVectorBuffer[VectorIndex] = FLinearColor(0,0,0,0);
			UniformVectorExpressions[VectorIndex]->GetNumberValue(MaterialRenderContext,TempVectorBuffer[VectorIndex]);
		}

		float* TempScalarBuffer = (float*)(TempVectorBuffer + UniformVectorExpressions.Num());
		for(int32 ScalarIndex = 0;ScalarIndex < UniformScalarExpressions.Num();++ScalarIndex)
		{
			FLinearColor VectorValue(0,0,0,0);
			UniformScalarExpressions[ScalarIndex]->GetNumberValue(MaterialRenderContext,VectorValue);
			TempScalarBuffer[ScalarIndex] = VectorValue.R;
		}

		void** ResourceTable = (void**)((uint8*)TempBuffer + UniformBufferStruct->GetLayout().ResourceOffset);
		check(((UPTRINT)ResourceTable & 0x7) == 0);

		// Cache 2D texture uniform expressions.
		for(int32 ExpressionIndex = 0;ExpressionIndex < Uniform2DTextureExpressions.Num();ExpressionIndex++)
		{
			const UTexture* Value;
			Uniform2DTextureExpressions[ExpressionIndex]->GetTextureValue(MaterialRenderContext,MaterialRenderContext.Material,Value);
			if(Value && Value->Resource)
			{
				*ResourceTable++ = Value->TextureReference.TextureReferenceRHI;
				*ResourceTable++ = Value->Resource->SamplerStateRHI;
			}
			else
			{
				*ResourceTable++ = GWhiteTexture->TextureRHI;
				*ResourceTable++ = GWhiteTexture->SamplerStateRHI;
			}
		}

		// Cache cube texture uniform expressions.
		for(int32 ExpressionIndex = 0;ExpressionIndex < UniformCubeTextureExpressions.Num();ExpressionIndex++)
		{
			const UTexture* Value;
			UniformCubeTextureExpressions[ExpressionIndex]->GetTextureValue(MaterialRenderContext,MaterialRenderContext.Material,Value);
			if(Value && Value->Resource)
			{
				*ResourceTable++ = Value->TextureReference.TextureReferenceRHI;
				*ResourceTable++ = Value->Resource->SamplerStateRHI;
			}
			else
			{
				*ResourceTable++ = GWhiteTexture->TextureRHI;
				*ResourceTable++ = GWhiteTexture->SamplerStateRHI;
			}
		}
		if (CommandListIfLocalMode)
		{
			check(OutLocalUniformBuffer);
			*OutLocalUniformBuffer = CommandListIfLocalMode->BuildLocalUniformBuffer(TempBuffer, UniformBufferStruct->GetSize(), UniformBufferStruct->GetLayout());
			check(OutLocalUniformBuffer->IsValid());
		}
		else
		{
			UniformBuffer = RHICreateUniformBuffer(TempBuffer, UniformBufferStruct->GetLayout(), UniformBuffer_MultiFrame);
			check(!OutLocalUniformBuffer->IsValid());
		}
	}

	return UniformBuffer;
}