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); } } }