Example #1
0
void FVertexFactory::Set(FRHICommandList& RHICmdList) const
{
	check(IsInitialized());
	for(int32 StreamIndex = 0;StreamIndex < Streams.Num();StreamIndex++)
	{
		const FVertexStream& Stream = Streams[StreamIndex];
		checkf(Stream.VertexBuffer->IsInitialized(), TEXT("Vertex buffer was not initialized! Stream %u, Stride %u, Name %s"), StreamIndex, Stream.Stride, *Stream.VertexBuffer->GetFriendlyName());
		RHICmdList.SetStreamSource( StreamIndex, Stream.VertexBuffer->VertexBufferRHI, Stream.Stride, Stream.Offset);
	}
}
void FVertexFactory::OffsetPositionInstanceStreams(FRHICommandList& RHICmdList, uint32 FirstVertex) const
{
	for(int32 StreamIndex = 0;StreamIndex < PositionStream.Num();StreamIndex++)
	{
		const FVertexStream& Stream = PositionStream[StreamIndex];
		if (Stream.bUseInstanceIndex)
		{
			RHICmdList.SetStreamSource( StreamIndex, Stream.VertexBuffer->VertexBufferRHI, Stream.Stride, Stream.Offset + Stream.Stride * FirstVertex);
		}
	}
}
void FVertexFactory::SetPositionStream(FRHICommandList& RHICmdList) const
{
	check(IsInitialized());
	// Set the predefined vertex streams.
	for(int32 StreamIndex = 0;StreamIndex < PositionStream.Num();StreamIndex++)
	{
		const FVertexStream& Stream = PositionStream[StreamIndex];
		check(Stream.VertexBuffer->IsInitialized());
		RHICmdList.SetStreamSource( StreamIndex, Stream.VertexBuffer->VertexBufferRHI, Stream.Stride, Stream.Offset);
	}
}
void FLightPropagationVolume::Visualise(FRHICommandList& RHICmdList, const FViewInfo& View) const
{
    SCOPED_DRAW_EVENT(RHICmdList, LpvVisualise);
    check(View.GetFeatureLevel() == ERHIFeatureLevel::SM5);

    TShaderMapRef<FLpvVisualiseVS> VertexShader(View.ShaderMap);
    TShaderMapRef<FLpvVisualiseGS> GeometryShader(View.ShaderMap);
    TShaderMapRef<FLpvVisualisePS> PixelShader(View.ShaderMap);

    RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
    RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI());
    RHICmdList.SetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_One, BF_One>::GetRHI());

    SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), LpvVisBoundShaderState, GSimpleElementVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader, *GeometryShader);

    VertexShader->SetParameters(RHICmdList, View);
    GeometryShader->SetParameters(RHICmdList, View);
    PixelShader->SetParameters(RHICmdList, this, View);

    RHICmdList.SetStreamSource(0, NULL, 0, 0);
    RHICmdList.DrawPrimitive(PT_PointList, 0, 1, 32 * 3);

    PixelShader->UnbindBuffers(RHICmdList);
}
void DrawRectangle(
	FRHICommandList& RHICmdList,
	float X,
	float Y,
	float SizeX,
	float SizeY,
	float U,
	float V,
	float SizeU,
	float SizeV,
	FIntPoint TargetSize,
	FIntPoint TextureSize,
	FShader* VertexShader,
	EDrawRectangleFlags Flags
	)
{
	float ClipSpaceQuadZ = 0.0f;

	DoDrawRectangleFlagOverride(Flags);

	// triangle if extending to left and top of the given rectangle, if it's not left top of the viewport it can cause artifacts
	if(X > 0.0f || Y > 0.0f)
	{
		// don't use triangle optimization
		Flags = EDRF_Default;
	}

	// Set up vertex uniform parameters for scaling and biasing the rectangle.
	// Note: Use DrawRectangle in the vertex shader to calculate the correct vertex position and uv.

	FDrawRectangleParameters Parameters;
	Parameters.PosScaleBias = FVector4(SizeX, SizeY, X, Y);
	Parameters.UVScaleBias = FVector4(SizeU, SizeV, U, V);

	Parameters.InvTargetSizeAndTextureSize = FVector4( 
		1.0f / TargetSize.X, 1.0f / TargetSize.Y, 
		1.0f / TextureSize.X, 1.0f / TextureSize.Y);

	SetUniformBufferParameterImmediate(RHICmdList, VertexShader->GetVertexShader(), VertexShader->GetUniformBufferParameter<FDrawRectangleParameters>(), Parameters);

	if(Flags == EDRF_UseTesselatedIndexBuffer)
	{
		// no vertex buffer needed as we compute it in VS
		RHICmdList.SetStreamSource(0, NULL, 0, 0);

		RHICmdList.DrawIndexedPrimitive(
			GTesselatedScreenRectangleIndexBuffer.IndexBufferRHI,
			PT_TriangleList,
			/*BaseVertexIndex=*/ 0,
			/*MinIndex=*/ 0,
			/*NumVertices=*/ GTesselatedScreenRectangleIndexBuffer.NumVertices(),
			/*StartIndex=*/ 0,
			/*NumPrimitives=*/ GTesselatedScreenRectangleIndexBuffer.NumPrimitives(),
			/*NumInstances=*/ 1
			);
	}
	else
	{
		RHICmdList.SetStreamSource(0, GScreenRectangleVertexBuffer.VertexBufferRHI, sizeof(FFilterVertex), 0);

		if (Flags == EDRF_UseTriangleOptimization)
		{
			// A single triangle spans the entire viewport this results in a quad that fill the viewport. This can increase rasterization efficiency
			// as we do not have a diagonal edge (through the center) for the rasterizer/span-dispatch. Although the actual benefit of this technique is dependent upon hardware.

			// We offset into the index buffer when using the triangle optimization to access the correct vertices.
			RHICmdList.DrawIndexedPrimitive(
				GScreenRectangleIndexBuffer.IndexBufferRHI,
				PT_TriangleList,
				/*BaseVertexIndex=*/ 0,
				/*MinIndex=*/ 0,
				/*NumVertices=*/ 3,
				/*StartIndex=*/ 6,
				/*NumPrimitives=*/ 1,
				/*NumInstances=*/ 1
				);
		}
		else
		{
			RHICmdList.SetStreamSource(0, GScreenRectangleVertexBuffer.VertexBufferRHI, sizeof(FFilterVertex), 0);

			RHICmdList.DrawIndexedPrimitive(
				GScreenRectangleIndexBuffer.IndexBufferRHI,
				PT_TriangleList,
				/*BaseVertexIndex=*/ 0,
				/*MinIndex=*/ 0,
				/*NumVertices=*/ 4,
				/*StartIndex=*/ 0,
				/*NumPrimitives=*/ 2,
				/*NumInstances=*/ 1
				);
		}
	}
}
void RunBenchmarkShader(FRHICommandList& RHICmdList, FVertexBufferRHIParamRef VertexThroughputBuffer, const FSceneView& View, TRefCountPtr<IPooledRenderTarget>& Src, float WorkScale)
{
	auto ShaderMap = GetGlobalShaderMap(View.GetFeatureLevel());

	TShaderMapRef<FPostProcessBenchmarkVS<VsMethod>> VertexShader(ShaderMap);
	TShaderMapRef<FPostProcessBenchmarkPS<PsMethod>> PixelShader(ShaderMap);

	bool bVertexTest = VsMethod == 1;
	FVertexDeclarationRHIParamRef VertexDeclaration = bVertexTest
		? GVertexThroughputDeclaration.DeclRHI
		: GFilterVertexDeclaration.VertexDeclarationRHI;

	static FGlobalBoundShaderState BoundShaderState;
	SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, VertexDeclaration, *VertexShader, *PixelShader);

	PixelShader->SetParameters(RHICmdList, View, Src);
	VertexShader->SetParameters(RHICmdList, View);

	if (bVertexTest)
	{
		// Vertex Tests

		uint32 TotalNumPrimitives = FMath::CeilToInt(GBenchmarkPrimitives * WorkScale);
		uint32 TotalNumVertices = TotalNumPrimitives * 3;

		while (TotalNumVertices != 0)
		{
			uint32 VerticesThisPass = FMath::Min(TotalNumVertices, GBenchmarkVertices);
			uint32 PrimitivesThisPass = VerticesThisPass / 3;

			RHICmdList.SetStreamSource(0, VertexThroughputBuffer, sizeof(FBenchmarkVertex), 0);
			RHICmdList.DrawPrimitive(PT_TriangleList, 0, PrimitivesThisPass, 1);

			TotalNumVertices -= VerticesThisPass;
		}
	}
	else
	{
		// Pixel Tests

		// single pass was not fine grained enough so we reduce the pass size based on the fractional part of WorkScale
		float TotalHeight = GBenchmarkResolution * WorkScale;

		// rounds up
		uint32 PassCount = (uint32)FMath::CeilToFloat(TotalHeight / GBenchmarkResolution);

		for (uint32 i = 0; i < PassCount; ++i)
		{
			float Top = i * GBenchmarkResolution;
			float Bottom = FMath::Min(Top + GBenchmarkResolution, TotalHeight);
			float LocalHeight = Bottom - Top;

			DrawRectangle(
				RHICmdList,
				0, 0,
				GBenchmarkResolution, LocalHeight,
				0, 0,
				GBenchmarkResolution, LocalHeight,
				FIntPoint(GBenchmarkResolution, GBenchmarkResolution),
				FIntPoint(GBenchmarkResolution, GBenchmarkResolution),
				*VertexShader,
				EDRF_Default);
		}
	}
}