void UpdateSceneCaptureContent_RenderThread(FSceneRenderer* SceneRenderer, FTextureRenderTargetResource* TextureRenderTarget, const FName OwnerName, const FResolveParams& ResolveParams, bool bUseSceneColorTexture) { FMemMark MemStackMark(FMemStack::Get()); // update any resources that needed a deferred update FDeferredUpdateResource::UpdateResources(); { #if WANTS_DRAW_MESH_EVENTS FString EventName; OwnerName.ToString(EventName); SCOPED_DRAW_EVENTF(SceneCapture, DEC_SCENE_ITEMS, TEXT("SceneCapture %s"), *EventName); #endif // Render the scene normally const FRenderTarget* Target = SceneRenderer->ViewFamily.RenderTarget; FIntRect ViewRect = SceneRenderer->Views[0].ViewRect; FIntRect UnconstrainedViewRect = SceneRenderer->Views[0].UnconstrainedViewRect; RHISetRenderTarget(Target->GetRenderTargetTexture(), NULL); RHIClear(true, FLinearColor::Black, false, 1.0f, false, 0, ViewRect); SceneRenderer->Render(); // Copy the captured scene into the destination texture if (bUseSceneColorTexture) { // Copy the captured scene into the destination texture RHISetRenderTarget(Target->GetRenderTargetTexture(), NULL); RHISetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); RHISetBlendState(TStaticBlendState<>::GetRHI()); TShaderMapRef<FScreenVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FScreenPS> PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); FRenderingCompositePassContext Context(SceneRenderer->Views[0]); VertexShader->SetParameters(SceneRenderer->Views[0]); PixelShader->SetParameters(TStaticSamplerState<SF_Point>::GetRHI(), GSceneRenderTargets.GetSceneColorTexture()); FIntPoint TargetSize(UnconstrainedViewRect.Width(), UnconstrainedViewRect.Height()); DrawRectangle( ViewRect.Min.X, ViewRect.Min.Y, ViewRect.Width(), ViewRect.Height(), ViewRect.Min.X, ViewRect.Min.Y, ViewRect.Width(), ViewRect.Height(), TargetSize, GSceneRenderTargets.GetBufferSizeXY(), EDRF_UseTriangleOptimization); } RHICopyToResolveTarget(TextureRenderTarget->GetRenderTargetTexture(), TextureRenderTarget->TextureRHI, false, ResolveParams); } delete SceneRenderer; }
/** Draws a full view quad that sets stencil to 1 anywhere that decals should not be projected. */ void StencilDecalMask(const FSceneView& View) { SCOPED_DRAW_EVENT(StencilDecalMask, DEC_SCENE_ITEMS); RHISetRasterizerState(TStaticRasterizerState<FM_Solid,CM_None>::GetRHI()); RHISetBlendState(TStaticBlendState<CW_NONE>::GetRHI()); RHISetRenderTarget(NULL, GSceneRenderTargets.GetSceneDepthSurface()); RHISetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f); // Write 1 to highest bit of stencil to areas that should not receive decals RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always,true,CF_Always,SO_Replace,SO_Replace,SO_Replace>::GetRHI(), 0x80); TShaderMapRef<FScreenVS> ScreenVertexShader(GetGlobalShaderMap()); TShaderMapRef<FStencilDecalMaskPS> PixelShader(GetGlobalShaderMap()); SetGlobalBoundShaderState(StencilDecalMaskBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *PixelShader); PixelShader->SetParameters(View); DrawRectangle( 0, 0, View.ViewRect.Width(), View.ViewRect.Height(), View.ViewRect.Min.X, View.ViewRect.Min.Y, View.ViewRect.Width(), View.ViewRect.Height(), FIntPoint(View.ViewRect.Width(), View.ViewRect.Height()), GSceneRenderTargets.GetBufferSizeXY(), EDRF_UseTriangleOptimization); }
void FRCPassPostProcessVisualizeBuffer::SetShaderTempl(const FRenderingCompositePassContext& Context) { TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessVisualizeBufferPS<bDrawingTile> > PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetPS(Context); }
static void SetMotionBlurShaderTempl(const FRenderingCompositePassContext& Context) { TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessMotionBlurPS<Quality> > PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); VertexShader->SetParameters(Context); PixelShader->SetParameters(Context); }
void FRCPassPostProcessHistogramReduce::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(PostProcessHistogramReduce, DEC_SCENE_ITEMS); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntPoint SrcSize = InputDesc->Extent; FIntPoint DestSize = PassOutputs[0].RenderTargetDesc.Extent; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef()); // set the state RHISetBlendState(TStaticBlendState<>::GetRHI()); RHISetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessHistogramReducePS> PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); // we currently assume the input is half res, one full res pixel less to avoid getting bilinear filtered input FIntPoint GatherExtent = (View.ViewRect.Size() - FIntPoint(1, 1)) / 2; uint32 LoopSizeValue = ComputeLoopSize(GatherExtent); PixelShader->SetPS(Context, LoopSizeValue); // Draw a quad mapping scene color to the view's render target DrawRectangle( 0, 0, DestSize.X, DestSize.Y, 0, 0, SrcSize.X, 0, DestSize, SrcSize, EDRF_UseTriangleOptimization); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void SetNoiseBlurShader(const FRenderingCompositePassContext& Context, float InRadius) { TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessNoiseBlurPS<Method> > PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(Context, InRadius); VertexShader->SetParameters(Context); }
void SetSubsurfaceSetupShader(const FRenderingCompositePassContext& Context) { TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessSubsurfaceSetupPS<SpecularCorrection> > PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(Context); VertexShader->SetParameters(Context); }
void FIESLightProfileBatchedElementParameters::BindShaders( FRHICommandList& RHICmdList, ERHIFeatureLevel::Type InFeatureLevel, const FMatrix& InTransform, const float InGamma, const FMatrix& ColorWeights, const FTexture* Texture ) { TShaderMapRef<FSimpleElementVS> VertexShader(GetGlobalShaderMap(InFeatureLevel)); TShaderMapRef<FIESLightProfilePS> PixelShader(GetGlobalShaderMap(InFeatureLevel)); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, InFeatureLevel, BoundShaderState, GSimpleElementVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); VertexShader->SetParameters(RHICmdList, InTransform); PixelShader->SetParameters(RHICmdList, Texture, BrightnessInLumens); }
void Radix008A( FRHICommandListImmediate & RHICmdList, FRadixPlan512* Plan, uint32 ParamSet, FUnorderedAccessViewRHIRef pUAV_Dst, FShaderResourceViewRHIRef pSRV_Src, uint32 ThreadCount, uint32 istride) { check(ParamSet < FFT_PARAM_SETS); // Setup execution configuration uint32 grid = ThreadCount / COHERENCY_GRANULARITY; FRadixFFTUniformParameters Parameters; Parameters.ThreadCount = Plan->PerFrame[ParamSet].ThreadCount; Parameters.ostride = Plan->PerFrame[ParamSet].ostride; Parameters.istride = Plan->PerFrame[ParamSet].istride; Parameters.pstride = Plan->PerFrame[ParamSet].pstride; Parameters.PhaseBase = Plan->PerFrame[ParamSet].PhaseBase; FRadixFFTUniformBufferRef UniformBuffer = FRadixFFTUniformBufferRef::CreateUniformBufferImmediate(Parameters, EUniformBufferUsage::UniformBuffer_SingleFrame); if (istride > 1) { TShaderMapRef<FRadix008A_CS> Radix008A_CS(GetGlobalShaderMap(GMaxRHIFeatureLevel)); RHICmdList.SetComputeShader(Radix008A_CS->GetComputeShader()); Radix008A_CS->SetParameters(RHICmdList, UniformBuffer); Radix008A_CS->SetParameters(RHICmdList, pSRV_Src, pUAV_Dst); RHICmdList.DispatchComputeShader(grid, 1, 1); Radix008A_CS->UnsetParameters(RHICmdList); } else { TShaderMapRef<FRadix008A_CS2> Radix008A_CS2(GetGlobalShaderMap(GMaxRHIFeatureLevel)); RHICmdList.SetComputeShader(Radix008A_CS2->GetComputeShader()); Radix008A_CS2->SetParameters(RHICmdList, UniformBuffer); Radix008A_CS2->SetParameters(RHICmdList, pSRV_Src, pUAV_Dst); RHICmdList.DispatchComputeShader(grid, 1, 1); Radix008A_CS2->UnsetParameters(RHICmdList); } }
void FMipLevelBatchedElementParameters::BindShaders(FRHICommandList& RHICmdList, ERHIFeatureLevel::Type InFeatureLevel, const FMatrix& InTransform, const float InGamma, const FMatrix& ColorWeights, const FTexture* Texture) { TShaderMapRef<FCubemapTexturePropertiesVS> VertexShader(GetGlobalShaderMap(InFeatureLevel)); TShaderMapRef<TPixelShader> PixelShader(GetGlobalShaderMap(InFeatureLevel)); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, InFeatureLevel, BoundShaderState, GSimpleElementVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); VertexShader->SetParameters(RHICmdList, InTransform); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); PixelShader->SetParameters(RHICmdList, Texture, ColorWeights, MipLevel, InGamma); }
void BeginRecompileGlobalShaders(const TArray<FShaderType*>& OutdatedShaderTypes, EShaderPlatform ShaderPlatform) { if( !FPlatformProperties::RequiresCookedData() ) { // Flush pending accesses to the existing global shaders. FlushRenderingCommands(); TShaderMap<FGlobalShaderType>* GlobalShaderMap = GetGlobalShaderMap(ShaderPlatform); for (int32 TypeIndex = 0; TypeIndex < OutdatedShaderTypes.Num(); TypeIndex++) { FGlobalShaderType* CurrentGlobalShaderType = OutdatedShaderTypes[TypeIndex]->GetGlobalShaderType(); if (CurrentGlobalShaderType) { UE_LOG(LogShaders, Log, TEXT("Flushing Global Shader %s"), CurrentGlobalShaderType->GetName()); GlobalShaderMap->RemoveShaderType(CurrentGlobalShaderType); //invalidate global bound shader states so they will be created with the new shaders the next time they are set (in SetGlobalBoundShaderState) for(TLinkedList<FGlobalBoundShaderStateResource*>::TIterator It(FGlobalBoundShaderStateResource::GetGlobalBoundShaderStateList());It;It.Next()) { BeginUpdateResourceRHI(*It); } } } VerifyGlobalShaders(ShaderPlatform, false); } }
void FSteamVRHMD::RenderTexture_RenderThread(FRHICommandListImmediate& RHICmdList, FTexture2DRHIParamRef BackBuffer, FTexture2DRHIParamRef SrcTexture) const { check(IsInRenderingThread()); if (WindowMirrorMode == 0) { return; } const uint32 ViewportWidth = BackBuffer->GetSizeX(); const uint32 ViewportHeight = BackBuffer->GetSizeY(); SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); const auto FeatureLevel = GMaxRHIFeatureLevel; auto ShaderMap = GetGlobalShaderMap(FeatureLevel); TShaderMapRef<FScreenVS> VertexShader(ShaderMap); TShaderMapRef<FScreenPS> PixelShader(ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, FeatureLevel, BoundShaderState, RendererModule->GetFilterVertexDeclaration().VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Bilinear>::GetRHI(), SrcTexture); if (WindowMirrorMode == 1) { // need to clear when rendering only one eye since the borders won't be touched by the DrawRect below RHICmdList.Clear(true, FLinearColor::Black, false, 0, false, 0, FIntRect()); RendererModule->DrawRectangle( RHICmdList, ViewportWidth / 4, 0, ViewportWidth / 2, ViewportHeight, 0.1f, 0.2f, 0.3f, 0.6f, FIntPoint(ViewportWidth, ViewportHeight), FIntPoint(1, 1), *VertexShader, EDRF_Default); } else if (WindowMirrorMode == 2) { RendererModule->DrawRectangle( RHICmdList, 0, 0, ViewportWidth, ViewportHeight, 0.0f, 0.0f, 1.0f, 1.0f, FIntPoint(ViewportWidth, ViewportHeight), FIntPoint(1, 1), *VertexShader, EDRF_Default); } }
/** Binds the mesh paint vertex and pixel shaders to the graphics device */ void SetMeshPaintDilateShaders(FRHICommandList& RHICmdList, ERHIFeatureLevel::Type InFeatureLevel, const FMatrix& InTransform, const float InGamma, const FMeshPaintDilateShaderParameters& InShaderParams ) { TShaderMapRef< TMeshPaintDilateVertexShader > VertexShader(GetGlobalShaderMap(InFeatureLevel)); TShaderMapRef< TMeshPaintDilatePixelShader > PixelShader(GetGlobalShaderMap(InFeatureLevel)); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, InFeatureLevel, BoundShaderState, GMeshPaintDilateVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); // Set vertex shader parameters VertexShader->SetParameters(RHICmdList, InTransform ); // Set pixel shader parameters PixelShader->SetParameters(RHICmdList, InGamma, InShaderParams ); }
// If bfullResourceResolve is true: A no-op draw call is submitted which resolves all pending states // If bFullResourceResolve is false, A no-op clear is submitted which resolves RT's only static void ResolvePendingRenderTarget(FRHICommandListImmediate& RHICmdList, IRendererModule* RendererModule, bool bFullResourceResolve = true) { #if GOOGLEVRHMD_SUPPORTED_PLATFORMS // HACK! Need to workaround UE4's caching mechanism. This causes the pending commands to actually apply to the device. class FFakeIndexBuffer : public FIndexBuffer { public: /** Initialize the RHI for this rendering resource */ void InitRHI() override { // Indices 0 - 5 are used for rendering a quad. Indices 6 - 8 are used for triangle optimization. const uint16 Indices[] = { 0, 1, 2, 2, 1, 3, 0, 4, 5 }; TResourceArray<uint16, INDEXBUFFER_ALIGNMENT> IndexBuffer; uint32 InternalNumIndices = ARRAY_COUNT(Indices); IndexBuffer.AddUninitialized(InternalNumIndices); FMemory::Memcpy(IndexBuffer.GetData(), Indices, InternalNumIndices * sizeof(uint16)); // Create index buffer. Fill buffer with initial data upon creation FRHIResourceCreateInfo CreateInfo(&IndexBuffer); IndexBufferRHI = RHICreateIndexBuffer(sizeof(uint16), IndexBuffer.GetResourceDataSize(), BUF_Static, CreateInfo); } }; static TGlobalResource<FFakeIndexBuffer> FakeIndexBuffer; if(bFullResourceResolve) { const auto FeatureLevel = GMaxRHIFeatureLevel; auto ShaderMap = GetGlobalShaderMap(FeatureLevel); TShaderMapRef<FScreenVS> VertexShader(ShaderMap); TShaderMapRef<FScreenPS> PixelShader(ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, FeatureLevel, BoundShaderState, RendererModule->GetFilterVertexDeclaration().VertexDeclarationRHI, *VertexShader, *PixelShader); RHICmdList.DrawIndexedPrimitive( FakeIndexBuffer.IndexBufferRHI, PT_TriangleList, /*BaseVertexIndex=*/ 0, /*MinIndex=*/ 0, /*NumVertices=*/ 0, /*StartIndex=*/ 0, /*NumPrimitives=*/ 0, /*NumInstances=*/ 1 ); } else { RHICmdList.ClearMRT(false, 0, nullptr, false, 0.0f, false, 0, FIntRect()); } RHICmdList.ImmediateFlush(EImmediateFlushType::FlushRHIThread); #endif }
/** Updates the downsized depth buffer with the current full resolution depth buffer. */ void FDeferredShadingSceneRenderer::UpdateDownsampledDepthSurface() { if (GSceneRenderTargets.UseDownsizedOcclusionQueries() && IsFeatureLevelSupported(GRHIShaderPlatform, ERHIFeatureLevel::SM3)) { RHISetRenderTarget(NULL, GSceneRenderTargets.GetSmallDepthSurface()); SCOPED_DRAW_EVENT(DownsampleDepth, DEC_SCENE_ITEMS); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { const FViewInfo& View = Views[ViewIndex]; // Set shaders and texture TShaderMapRef<FScreenVS> ScreenVertexShader(GetGlobalShaderMap()); TShaderMapRef<FDownsampleSceneDepthPS> PixelShader(GetGlobalShaderMap()); extern TGlobalResource<FFilterVertexDeclaration> GFilterVertexDeclaration; SetGlobalBoundShaderState(DownsampleDepthBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *PixelShader); RHISetBlendState(TStaticBlendState<CW_NONE>::GetRHI()); RHISetRasterizerState(TStaticRasterizerState<FM_Solid,CM_None>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<true,CF_Always>::GetRHI()); PixelShader->SetParameters(View); const uint32 DownsampledX = FMath::Trunc(View.ViewRect.Min.X / GSceneRenderTargets.GetSmallColorDepthDownsampleFactor()); const uint32 DownsampledY = FMath::Trunc(View.ViewRect.Min.Y / GSceneRenderTargets.GetSmallColorDepthDownsampleFactor()); const uint32 DownsampledSizeX = FMath::Trunc(View.ViewRect.Width() / GSceneRenderTargets.GetSmallColorDepthDownsampleFactor()); const uint32 DownsampledSizeY = FMath::Trunc(View.ViewRect.Height() / GSceneRenderTargets.GetSmallColorDepthDownsampleFactor()); RHISetViewport(DownsampledX, DownsampledY, 0.0f, DownsampledX + DownsampledSizeX, DownsampledY + DownsampledSizeY, 1.0f); DrawRectangle( 0, 0, DownsampledSizeX, DownsampledSizeY, View.ViewRect.Min.X, View.ViewRect.Min.Y, View.ViewRect.Width(), View.ViewRect.Height(), FIntPoint(DownsampledSizeX, DownsampledSizeY), GSceneRenderTargets.GetBufferSizeXY(), EDRF_UseTriangleOptimization); } } }
void FRCPassPostProcessBusyWait::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(BusyWait, DEC_SCENE_ITEMS); const FSceneView& View = Context.View; FIntRect SrcRect = View.ViewRect; FIntRect DestRect = View.UnscaledViewRect; const FSceneRenderTargetItem& DestRenderTarget = GSceneRenderTargets.LightAttenuation->GetRenderTargetItem(); // Set the view family's render target/viewport. RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(DestRect); // set the state RHISetBlendState(TStaticBlendState<>::GetRHI()); RHISetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessBusyWaitPS> PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetPS(Context); // Draw a quad mapping scene color to the view's render target DrawRectangle( 0, 0, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestRect.Size(), SrcRect.Size(), EDRF_UseTriangleOptimization); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FOculusRiftHMD::CopyTexture_RenderThread(FRHICommandListImmediate& RHICmdList, FTexture2DRHIParamRef DstTexture, FTexture2DRHIParamRef SrcTexture, FIntRect DstRect, FIntRect SrcRect) const { check(IsInRenderingThread()); if (DstRect.IsEmpty()) { DstRect = FIntRect(0, 0, DstTexture->GetSizeX(), DstTexture->GetSizeY()); } const uint32 ViewportWidth = DstRect.Width(); const uint32 ViewportHeight = DstRect.Height(); const FIntPoint TargetSize(ViewportWidth, ViewportHeight); const float SrcTextureWidth = SrcTexture->GetSizeX(); const float SrcTextureHeight = SrcTexture->GetSizeY(); float U = 0.f, V = 0.f, USize = 1.f, VSize = 1.f; if (!SrcRect.IsEmpty()) { U = SrcRect.Min.X / SrcTextureWidth; V = SrcRect.Min.Y / SrcTextureHeight; USize = SrcRect.Width() / SrcTextureWidth; VSize = SrcRect.Height() / SrcTextureHeight; } SetRenderTarget(RHICmdList, DstTexture, FTextureRHIRef()); RHICmdList.SetViewport(DstRect.Min.X, DstRect.Min.Y, 0, DstRect.Max.X, DstRect.Max.Y, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); const auto FeatureLevel = GMaxRHIFeatureLevel; auto ShaderMap = GetGlobalShaderMap(FeatureLevel); TShaderMapRef<FScreenVS> VertexShader(ShaderMap); TShaderMapRef<FScreenPS> PixelShader(ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, FeatureLevel, BoundShaderState, RendererModule->GetFilterVertexDeclaration().VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Bilinear>::GetRHI(), SrcTexture); RendererModule->DrawRectangle( RHICmdList, 0, 0, ViewportWidth, ViewportHeight, U, V, USize, VSize, TargetSize, FIntPoint(1, 1), *VertexShader, EDRF_Default); }
void RunBenchmarkShader(const FSceneView& View, TRefCountPtr<IPooledRenderTarget>& Src, uint32 Count) { TShaderMapRef<FPostProcessBenchmarkVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessBenchmarkPS<Method> > PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(View, Src); VertexShader->SetParameters(View); for(uint32 i = 0; i < Count; ++i) { DrawRectangle( 0, 0, GBenchmarkResolution, GBenchmarkResolution, 0, 0, GBenchmarkResolution, GBenchmarkResolution, FIntPoint(GBenchmarkResolution, GBenchmarkResolution), FIntPoint(GBenchmarkResolution, GBenchmarkResolution), EDRF_Default); } }
template<uint32 TextureType> void VisualizeTextureForTextureType(const FVisualizeTextureData& Data) { TShaderMapRef<FScreenVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<VisualizeTexturePS<TextureType> > PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(Data); DrawRectangle( // XY 0, 0, // SizeXY GSceneRenderTargets.GetBufferSizeXY().X, GSceneRenderTargets.GetBufferSizeXY().Y, // UV Data.Tex00.X, Data.Tex00.Y, // SizeUV Data.Tex11.X - Data.Tex00.X, Data.Tex11.Y - Data.Tex00.Y, // TargetSize GSceneRenderTargets.GetBufferSizeXY(), // TextureSize FIntPoint(1, 1), EDRF_UseTriangleOptimization); }
static void ResolveColorWideInternal2( FRHICommandList& RHICmdList, const ERHIFeatureLevel::Type CurrentFeatureLevel, const FTextureRHIRef& SrcTexture, const FIntPoint& SrcOrigin) { auto ShaderMap = GetGlobalShaderMap(CurrentFeatureLevel); TShaderMapRef<FWideCustomResolveVS> VertexShader(ShaderMap); TShaderMapRef<FWideCustomResolvePS<MSAA, Width>> PixelShader(ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, CurrentFeatureLevel, BoundShaderState, GetVertexDeclarationFVector4(), *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, SrcTexture, SrcOrigin); RHICmdList.DrawPrimitive(PT_TriangleList, 0, 1, 1); }
void FD3D11DynamicRHI::IssueLongGPUTask() { if (GMaxRHIFeatureLevel >= ERHIFeatureLevel::SM4) { int32 LargestViewportIndex = INDEX_NONE; int32 LargestViewportPixels = 0; for (int32 ViewportIndex = 0; ViewportIndex < Viewports.Num(); ViewportIndex++) { FD3D11Viewport* Viewport = Viewports[ViewportIndex]; if (Viewport->GetSizeXY().X * Viewport->GetSizeXY().Y > LargestViewportPixels) { LargestViewportPixels = Viewport->GetSizeXY().X * Viewport->GetSizeXY().Y; LargestViewportIndex = ViewportIndex; } } if (LargestViewportIndex >= 0) { FD3D11Viewport* Viewport = Viewports[LargestViewportIndex]; FRHICommandList_RecursiveHazardous RHICmdList(this); SetRenderTarget(RHICmdList, Viewport->GetBackBuffer(), FTextureRHIRef()); RHICmdList.SetBlendState(TStaticBlendState<CW_RGBA, BO_Add, BF_One, BF_One>::GetRHI(), FLinearColor::Black); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI(), 0); RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); auto ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); TShaderMapRef<TOneColorVS<true> > VertexShader(ShaderMap); TShaderMapRef<FLongGPUTaskPS> PixelShader(ShaderMap); RHICmdList.SetLocalBoundShaderState(RHICmdList.BuildLocalBoundShaderState(GD3D11Vector4VertexDeclaration.VertexDeclarationRHI, VertexShader->GetVertexShader(), FHullShaderRHIRef(), FDomainShaderRHIRef(), PixelShader->GetPixelShader(), FGeometryShaderRHIRef())); // Draw a fullscreen quad FVector4 Vertices[4]; Vertices[0].Set( -1.0f, 1.0f, 0, 1.0f ); Vertices[1].Set( 1.0f, 1.0f, 0, 1.0f ); Vertices[2].Set( -1.0f, -1.0f, 0, 1.0f ); Vertices[3].Set( 1.0f, -1.0f, 0, 1.0f ); DrawPrimitiveUP(RHICmdList, PT_TriangleStrip, 2, Vertices, sizeof(Vertices[0])); // Implicit flush. Always call flush when using a command list in RHI implementations before doing anything else. This is super hazardous. } } }
void FRCPassPostProcessHistogram::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(PostProcessHistogram, DEC_SCENE_ITEMS); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntPoint SrcSize = InputDesc->Extent; FIntRect DestRect = View.ViewRect; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); TShaderMapRef<FPostProcessHistogramCS> ComputeShader(GetGlobalShaderMap()); RHISetComputeShader(ComputeShader->GetComputeShader()); RHISetRenderTarget(FTextureRHIRef(), FTextureRHIRef()); // set destination check(DestRenderTarget.UAV); RHISetUAVParameter(ComputeShader->GetComputeShader(), ComputeShader->HistogramRWTexture.GetBaseIndex(), DestRenderTarget.UAV); // we currently assume the input is half res, one full res pixel less to avoid getting bilinear filtered input FIntPoint GatherExtent = (DestRect.Size() - FIntPoint(1, 1)) / 2; FIntPoint ThreadGroupCountValue = ComputeThreadGroupCount(GatherExtent); ComputeShader->SetCS(Context, ThreadGroupCountValue, (DestRect.Min + FIntPoint(1, 1)) / 2, GatherExtent); DispatchComputeShader(*ComputeShader, ThreadGroupCountValue.X, ThreadGroupCountValue.Y, 1); // un-set destination RHISetUAVParameter(ComputeShader->GetComputeShader(), ComputeShader->HistogramRWTexture.GetBaseIndex(), NULL); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
/** * Forces a recompile of the global shaders. */ void RecompileGlobalShaders() { if( !FPlatformProperties::RequiresCookedData() ) { // Flush pending accesses to the existing global shaders. FlushRenderingCommands(); GetGlobalShaderMap(GRHIShaderPlatform)->Empty(); VerifyGlobalShaders(GRHIShaderPlatform, false); GShaderCompilingManager->ProcessAsyncResults(false, true); //invalidate global bound shader states so they will be created with the new shaders the next time they are set (in SetGlobalBoundShaderState) for(TLinkedList<FGlobalBoundShaderStateResource*>::TIterator It(FGlobalBoundShaderStateResource::GetGlobalBoundShaderStateList());It;It.Next()) { BeginUpdateResourceRHI(*It); } } }
/** Saves the global shader map as a file for the target platform. */ FString SaveGlobalShaderFile(EShaderPlatform Platform, FString SavePath) { TShaderMap<FGlobalShaderType>* GlobalShaderMap = GetGlobalShaderMap(Platform); // Wait until all global shaders are compiled if (GShaderCompilingManager) { GShaderCompilingManager->ProcessAsyncResults(false, true); } TArray<uint8> GlobalShaderData; FMemoryWriter MemoryWriter(GlobalShaderData); SerializeGlobalShaders(MemoryWriter, GlobalShaderMap); // make the final name FString FullPath = SavePath / GetGlobalShaderCacheFilename(Platform); verify(FFileHelper::SaveArrayToFile(GlobalShaderData, *FullPath)); return FullPath; }
void UVaOceanSimulatorComponent::UpdateDisplacementMap(float WorldTime) { if (DisplacementTarget == NULL || GradientTarget == NULL) return; // ---------------------------- H(0) -> H(t), D(x, t), D(y, t) -------------------------------- FUpdateSpectrumCSPerFrame UpdateSpectrumCSPerFrameParams; UpdateSpectrumCSPerFrameParams.g_Time = WorldTime * OceanConfig.TimeScale; UpdateSpectrumCSPerFrameParams.g_ChoppyScale = OceanConfig.ChoppyScale; UpdateSpectrumCSPerFrameParams.m_pSRV_H0 = m_pSRV_H0; UpdateSpectrumCSPerFrameParams.m_pSRV_Omega = m_pSRV_Omega; UpdateSpectrumCSPerFrameParams.m_pUAV_Ht = m_pUAV_Ht; ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER( UpdateSpectrumCSCommand, FUpdateSpectrumCSImmutable, ImmutableParams, UpdateSpectrumCSImmutableParams, FUpdateSpectrumCSPerFrame, PerFrameParams, UpdateSpectrumCSPerFrameParams, { FUpdateSpectrumUniformParameters Parameters; Parameters.Time = PerFrameParams.g_Time; FUpdateSpectrumUniformBufferRef UniformBuffer = FUpdateSpectrumUniformBufferRef::CreateUniformBufferImmediate(Parameters, UniformBuffer_SingleUse); TShaderMapRef<FUpdateSpectrumCS> UpdateSpectrumCS(GetGlobalShaderMap()); RHISetComputeShader(UpdateSpectrumCS->GetComputeShader()); UpdateSpectrumCS->SetParameters(ImmutableParams.g_ActualDim, ImmutableParams.g_InWidth, ImmutableParams.g_OutWidth, ImmutableParams.g_OutHeight, ImmutableParams.g_DtxAddressOffset, ImmutableParams.g_DtyAddressOffset); UpdateSpectrumCS->SetParameters(UniformBuffer, PerFrameParams.m_pSRV_H0, PerFrameParams.m_pSRV_Omega); UpdateSpectrumCS->SetOutput(PerFrameParams.m_pUAV_Ht); uint32 group_count_x = (ImmutableParams.g_ActualDim + BLOCK_SIZE_X - 1) / BLOCK_SIZE_X; uint32 group_count_y = (ImmutableParams.g_ActualDim + BLOCK_SIZE_Y - 1) / BLOCK_SIZE_Y; RHIDispatchComputeShader(group_count_x, group_count_y, 1); UpdateSpectrumCS->UnsetParameters(); UpdateSpectrumCS->UnbindBuffers(); });
void RunBenchmarkShader(FRHICommandList& RHICmdList, const FSceneView& View, TRefCountPtr<IPooledRenderTarget>& Src, float WorkScale) { auto ShaderMap = GetGlobalShaderMap(View.GetFeatureLevel()); TShaderMapRef<FPostProcessBenchmarkVS> VertexShader(ShaderMap); TShaderMapRef<FPostProcessBenchmarkPS<Method> > PixelShader(ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, View, Src); VertexShader->SetParameters(RHICmdList, View); // 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); } }
void FRCPassPostProcessPassThrough::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(PassThrough, DEC_SCENE_ITEMS); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; FIntPoint TexSize = InputDesc->Extent; // we assume the input and output is full resolution FIntPoint SrcSize = InputDesc->Extent; FIntPoint DestSize = Dest ? Dest->GetDesc().Extent : PassOutputs[0].RenderTargetDesc.Extent; // e.g. 4 means the input texture is 4x smaller than the buffer size uint32 InputScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / SrcSize.X; uint32 OutputScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / DestSize.X; FIntRect SrcRect = View.ViewRect / InputScaleFactor; FIntRect DestRect = View.ViewRect / OutputScaleFactor; const FSceneRenderTargetItem& DestRenderTarget = Dest ? Dest->GetRenderTargetItem() : PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(0, 0, 0.0f, DestSize.X, DestSize.Y, 1.0f); // set the state if(bAdditiveBlend) { RHISetBlendState(TStaticBlendState<CW_RGB,BO_Add,BF_One,BF_One,BO_Add,BF_One,BF_One>::GetRHI()); } else { RHISetBlendState(TStaticBlendState<>::GetRHI()); } RHISetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessPassThroughPS> PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); VertexShader->SetParameters(Context); PixelShader->SetParameters(Context); // Draw a quad mapping scene color to the view's render target DrawRectangle( DestRect.Min.X, DestRect.Min.Y, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestSize, SrcSize, EDRF_UseTriangleOptimization); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
static void ClearQuadSetup( FRHICommandList& RHICmdList, ERHIFeatureLevel::Type FeatureLevel, bool bClearColor, int32 NumClearColors, const FLinearColor* ClearColorArray, bool bClearDepth, float Depth, bool bClearStencil, uint32 Stencil ) { // Set new states FBlendStateRHIParamRef BlendStateRHI; if (NumClearColors <= 1) { BlendStateRHI = bClearColor ? TStaticBlendState<>::GetRHI() : TStaticBlendState<CW_NONE>::GetRHI(); } else { BlendStateRHI = bClearColor ? TStaticBlendState<>::GetRHI() : TStaticBlendStateWriteMask<CW_NONE,CW_NONE,CW_NONE,CW_NONE,CW_NONE,CW_NONE,CW_NONE,CW_NONE>::GetRHI(); } const FDepthStencilStateRHIParamRef DepthStencilStateRHI = (bClearDepth && bClearStencil) ? TStaticDepthStencilState< true, CF_Always, true,CF_Always,SO_Replace,SO_Replace,SO_Replace, false,CF_Always,SO_Replace,SO_Replace,SO_Replace, 0xff,0xff >::GetRHI() : bClearDepth ? TStaticDepthStencilState<true, CF_Always>::GetRHI() : bClearStencil ? TStaticDepthStencilState< false, CF_Always, true,CF_Always,SO_Replace,SO_Replace,SO_Replace, false,CF_Always,SO_Replace,SO_Replace,SO_Replace, 0xff,0xff >::GetRHI() : TStaticDepthStencilState<false, CF_Always>::GetRHI(); RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); RHICmdList.SetBlendState(BlendStateRHI); RHICmdList.SetDepthStencilState(DepthStencilStateRHI); auto ShaderMap = GetGlobalShaderMap(FeatureLevel); // Set the new shaders TShaderMapRef<TOneColorVS<true> > VertexShader(ShaderMap); FOneColorPS* PixelShader = NULL; // Set the shader to write to the appropriate number of render targets // On AMD PC hardware, outputting to a color index in the shader without a matching render target set has a significant performance hit if (NumClearColors <= 1) { TShaderMapRef<TOneColorPixelShaderMRT<1> > MRTPixelShader(ShaderMap); PixelShader = *MRTPixelShader; } else if (NumClearColors == 2) { TShaderMapRef<TOneColorPixelShaderMRT<2> > MRTPixelShader(ShaderMap); PixelShader = *MRTPixelShader; } else if (NumClearColors == 3) { TShaderMapRef<TOneColorPixelShaderMRT<3> > MRTPixelShader(ShaderMap); PixelShader = *MRTPixelShader; } else if (NumClearColors == 4) { TShaderMapRef<TOneColorPixelShaderMRT<4> > MRTPixelShader(ShaderMap); PixelShader = *MRTPixelShader; } else if (NumClearColors == 5) { TShaderMapRef<TOneColorPixelShaderMRT<5> > MRTPixelShader(ShaderMap); PixelShader = *MRTPixelShader; } else if (NumClearColors == 6) { TShaderMapRef<TOneColorPixelShaderMRT<6> > MRTPixelShader(ShaderMap); PixelShader = *MRTPixelShader; } else if (NumClearColors == 7) { TShaderMapRef<TOneColorPixelShaderMRT<7> > MRTPixelShader(ShaderMap); PixelShader = *MRTPixelShader; } else if (NumClearColors == 8) { TShaderMapRef<TOneColorPixelShaderMRT<8> > MRTPixelShader(ShaderMap); PixelShader = *MRTPixelShader; } SetGlobalBoundShaderState(RHICmdList, FeatureLevel, GClearMRTBoundShaderState[FMath::Max(NumClearColors - 1, 0)], GetVertexDeclarationFVector4(), *VertexShader, PixelShader); PixelShader->SetColors(RHICmdList, ClearColorArray, NumClearColors); }
void FGoogleVRHMD::RenderTexture_RenderThread(FRHICommandListImmediate& RHICmdList, FTexture2DRHIParamRef BackBuffer, FTexture2DRHIParamRef SrcTexture) const { check(IsInRenderingThread()); const uint32 ViewportWidth = BackBuffer->GetSizeX(); const uint32 ViewportHeight = BackBuffer->GetSizeY(); const uint32 TextureWidth = SrcTexture->GetSizeX(); const uint32 TextureHeight = SrcTexture->GetSizeY(); //UE_LOG(LogHMD, Log, TEXT("RenderTexture_RenderThread() Viewport:(%d, %d) Texture:(%d, %d) BackBuffer=%p SrcTexture=%p"), ViewportWidth, ViewportHeight, TextureWidth, TextureHeight, BackBuffer, SrcTexture); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); #if GOOGLEVRHMD_SUPPORTED_PLATFORMS if(IsUsingGVRApiDistortionCorrection()) { if(!bDistortionCorrectionEnabled) { return; } // Perform render if(!bUseOffscreenFramebuffers) { // With proper resolution scaling, this should always be true! check(ViewportWidth == TextureWidth); check(ViewportHeight == TextureHeight); // Set target to back buffer SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f); ResolvePendingRenderTarget(RHICmdList, RendererModule); gvr_distort_to_screen(GVRAPI, *reinterpret_cast<GLuint*>(SrcTexture->GetNativeResource()), CachedDistortedRenderTextureParams, &CachedPose, &CachedFuturePoseTime); } else { if(!IsDeviceScanlineRacingEnabled()) { // With proper resolution scaling, this should always be true! check(ViewportWidth == TextureWidth); check(ViewportHeight == TextureHeight); // Set target to back buffer SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f); ResolvePendingRenderTarget(RHICmdList, RendererModule); } gvr_distort_offscreen_framebuffer_to_screen(GVRAPI, CustomPresent->GetFrameBufferId(), CachedDistortedRenderTextureParams, &CachedPose, &CachedFuturePoseTime); } } else // falls through on purpose #endif // GOOGLEVRHMD_SUPPORTED_PLATFORMS // Just render directly to output { SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f); const auto FeatureLevel = GMaxRHIFeatureLevel; auto ShaderMap = GetGlobalShaderMap(FeatureLevel); TShaderMapRef<FScreenVS> VertexShader(ShaderMap); TShaderMapRef<FScreenPS> PixelShader(ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, FeatureLevel, BoundShaderState, RendererModule->GetFilterVertexDeclaration().VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Bilinear>::GetRHI(), SrcTexture); RendererModule->DrawRectangle( RHICmdList, 0, 0, ViewportWidth, ViewportHeight, 0.0f, 0.0f, 1.0f, 1.0f, FIntPoint(ViewportWidth, ViewportHeight), FIntPoint(1, 1), *VertexShader, EDRF_Default); } }
void FRCPassPostProcessVisualizeBuffer::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(VisualizeBuffer, DEC_SCENE_ITEMS); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntRect SrcRect = View.ViewRect; FIntRect DestRect = View.ViewRect; FIntPoint SrcSize = InputDesc->Extent; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(DestRect); // set the state RHISetBlendState(TStaticBlendState<>::GetRHI()); RHISetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); SetShaderTempl<false>(Context); // Draw a quad mapping scene color to the view's render target DrawRectangle( 0, 0, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestRect.Size(), SrcSize, EDRF_UseTriangleOptimization); // Now draw the requested tiles into the grid TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessVisualizeBufferPS<true> > PixelShader(GetGlobalShaderMap()); RHISetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_SourceAlpha, BF_InverseSourceAlpha>::GetRHI()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetPS(Context); // Track the name and position of each tile we draw so we can write text labels over them struct LabelRecord { FString Label; int32 LocationX; int32 LocationY; }; TArray<LabelRecord> Labels; const int32 MaxTilesX = 4; const int32 MaxTilesY = 4; const int32 TileWidth = DestRect.Width() / MaxTilesX; const int32 TileHeight = DestRect.Height() / MaxTilesY; int32 CurrentTileIndex = 0; for (TArray<TileData>::TConstIterator It = Tiles.CreateConstIterator(); It; ++It, ++CurrentTileIndex) { FRenderingCompositeOutputRef Tile = It->Source; if (Tile.IsValid()) { FTextureRHIRef Texture = Tile.GetOutput()->PooledRenderTarget->GetRenderTargetItem().TargetableTexture; int32 TileX = CurrentTileIndex % MaxTilesX; int32 TileY = CurrentTileIndex / MaxTilesX; PixelShader->SetSourceTexture(Texture); DrawRectangle( TileX * TileWidth, TileY * TileHeight, TileWidth, TileHeight, SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestRect.Size(), SrcSize, EDRF_Default); Labels.Add(LabelRecord()); Labels.Last().Label = It->Name; Labels.Last().LocationX = 8 + TileX * TileWidth; Labels.Last().LocationY = (TileY + 1) * TileHeight - 19; } } // Draw tile labels // this is a helper class for FCanvas to be able to get screen size class FRenderTargetTemp : public FRenderTarget { public: const FSceneView& View; const FTexture2DRHIRef Texture; FRenderTargetTemp(const FSceneView& InView, const FTexture2DRHIRef InTexture) : View(InView), Texture(InTexture) { } virtual FIntPoint GetSizeXY() const { return View.ViewRect.Size(); }; virtual const FTexture2DRHIRef& GetRenderTargetTexture() const { return Texture; } } TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture); FCanvas Canvas(&TempRenderTarget, NULL, ViewFamily.CurrentRealTime, ViewFamily.CurrentWorldTime, ViewFamily.DeltaWorldTime); FLinearColor LabelColor(1, 1, 0); for (auto It = Labels.CreateConstIterator(); It; ++It) { Canvas.DrawShadowedString(It->LocationX, It->LocationY, *It->Label, GetStatsFont(), LabelColor); } Canvas.Flush(); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }