You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 3517651 by Ben.Woodhouse Integrate from //UE4/Main/...@3517493 to //UE4/Dev-Console/... Change 3519614 by Ben.Woodhouse Disable XGE shader compile Change 3524092 by Ben.Woodhouse FastVRam configurability - expose cvars to control fast vram usage for many rendertargets and buffers so that licensees can configure and find good values. Add support for tweaking values at runtime Change 3530731 by Luke.Thatcher [CONSOLE] [STREAMS] [^] Merging //UE4/Dev-Main (CL 3530708) to Dev-Console (//UE4/Dev-Console) Change 3537544 by Daniel.Eldar [General] Fixed an issue where the level streamer would not stream in a level until it finished streaming out another one. #jira UE-46954 Change 3540227 by Ben.Woodhouse Integrate from //UE4/Main/...@3539942 to //UE4/Dev-Console/... Change 3548390 by Keith.Judge Edigrate 3547845 to Dev-Console. Fix for UE-46826 - Correct mismatching game content base directories when using the network file server layer #jira UE-47570 Change 3563801 by Luke.Thatcher [CONSOLE] [STREAMS] [^] Merging //UE4/Dev-Main (CL 3557944) to Dev-Console (//UE4/Dev-Console) Change 3566413 by Luke.Thatcher [CONSOLE] [~] Fix build warning from bad merge of NetworkFileServerConnection.cpp - CL 3512255 renamed GameDir to ProjectDir, but we lost this change in the merge. Change 3566420 by Daniel.Eldar [General] Added a toggle vibration option to ShooterGame. #jira UE-47776 Change 3570476 by Ben.Woodhouse Fix for static analysis failure (disable innoccuous warning) #jira UE-48003 Change 3571837 by Ben.Woodhouse Integrate from //UE4/Main/...@3571062 to //UE4/Dev-Console/... Change 3572554 by Ben.Woodhouse Fix static analysis warning (disabling the warning didn't work) #jira UE-48050 [CL 3573409 by Joe Barnes in Main branch]
454 lines
16 KiB
C++
454 lines
16 KiB
C++
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
PostProcessDownsample.cpp: Post processing down sample implementation.
|
|
=============================================================================*/
|
|
|
|
#include "PostProcess/PostProcessDownsample.h"
|
|
#include "ClearQuad.h"
|
|
#include "StaticBoundShaderState.h"
|
|
#include "SceneUtils.h"
|
|
#include "PostProcess/SceneRenderTargets.h"
|
|
#include "PostProcess/SceneFilterRendering.h"
|
|
#include "SceneRenderTargetParameters.h"
|
|
#include "SceneRendering.h"
|
|
#include "PipelineStateCache.h"
|
|
|
|
const int32 GDownsampleTileSizeX = 8;
|
|
const int32 GDownsampleTileSizeY = 8;
|
|
|
|
/** Encapsulates the post processing down sample pixel shader. */
|
|
template <uint32 Method>
|
|
class FPostProcessDownsamplePS : public FGlobalShader
|
|
{
|
|
DECLARE_SHADER_TYPE(FPostProcessDownsamplePS, Global);
|
|
|
|
static bool ShouldCache(EShaderPlatform Platform)
|
|
{
|
|
return Method != 2 || IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM4);
|
|
}
|
|
|
|
static void ModifyCompilationEnvironment(EShaderPlatform Platform, FShaderCompilerEnvironment& OutEnvironment)
|
|
{
|
|
FGlobalShader::ModifyCompilationEnvironment(Platform,OutEnvironment);
|
|
OutEnvironment.SetDefine(TEXT("METHOD"), Method);
|
|
}
|
|
|
|
/** Default constructor. */
|
|
FPostProcessDownsamplePS() {}
|
|
|
|
public:
|
|
FPostProcessPassParameters PostprocessParameter;
|
|
FDeferredPixelShaderParameters DeferredParameters;
|
|
FShaderParameter DownsampleParams;
|
|
|
|
/** Initialization constructor. */
|
|
FPostProcessDownsamplePS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
|
|
: FGlobalShader(Initializer)
|
|
{
|
|
PostprocessParameter.Bind(Initializer.ParameterMap);
|
|
DeferredParameters.Bind(Initializer.ParameterMap);
|
|
DownsampleParams.Bind(Initializer.ParameterMap, TEXT("DownsampleParams"));
|
|
}
|
|
|
|
// FShader interface.
|
|
virtual bool Serialize(FArchive& Ar) override
|
|
{
|
|
bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
|
|
Ar << PostprocessParameter << DeferredParameters << DownsampleParams;
|
|
return bShaderHasOutdatedParameters;
|
|
}
|
|
|
|
void SetParameters(const FRenderingCompositePassContext& Context, const FPooledRenderTargetDesc* InputDesc)
|
|
{
|
|
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();
|
|
|
|
FGlobalShader::SetParameters<FViewUniformShaderParameters>(Context.RHICmdList, ShaderRHI, Context.View.ViewUniformBuffer);
|
|
DeferredParameters.Set(Context.RHICmdList, ShaderRHI, Context.View, MD_PostProcess);
|
|
|
|
// filter only if needed for better performance
|
|
FSamplerStateRHIParamRef Filter = (Method == 2) ?
|
|
TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI():
|
|
TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
|
|
|
{
|
|
float PixelScale = (Method == 2) ? 0.5f : 1.0f;
|
|
|
|
FVector4 DownsampleParamsValue(PixelScale / InputDesc->Extent.X, PixelScale / InputDesc->Extent.Y, 0, 0);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, DownsampleParams, DownsampleParamsValue);
|
|
}
|
|
|
|
PostprocessParameter.SetPS(ShaderRHI, Context, Filter);
|
|
}
|
|
|
|
static const TCHAR* GetSourceFilename()
|
|
{
|
|
return TEXT("/Engine/Private/PostProcessDownsample.usf");
|
|
}
|
|
|
|
static const TCHAR* GetFunctionName()
|
|
{
|
|
return TEXT("MainPS");
|
|
}
|
|
};
|
|
|
|
// #define avoids a lot of code duplication
|
|
#define VARIATION1(A) typedef FPostProcessDownsamplePS<A> FPostProcessDownsamplePS##A; \
|
|
IMPLEMENT_SHADER_TYPE2(FPostProcessDownsamplePS##A, SF_Pixel);
|
|
|
|
VARIATION1(0) VARIATION1(1) VARIATION1(2)
|
|
#undef VARIATION1
|
|
|
|
|
|
/** Encapsulates the post processing down sample vertex shader. */
|
|
class FPostProcessDownsampleVS : public FGlobalShader
|
|
{
|
|
DECLARE_SHADER_TYPE(FPostProcessDownsampleVS,Global);
|
|
public:
|
|
|
|
static bool ShouldCache(EShaderPlatform Platform)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/** Default constructor. */
|
|
FPostProcessDownsampleVS() {}
|
|
|
|
/** Initialization constructor. */
|
|
FPostProcessDownsampleVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer):
|
|
FGlobalShader(Initializer)
|
|
{
|
|
}
|
|
|
|
/** Serializer */
|
|
virtual bool Serialize(FArchive& Ar) override
|
|
{
|
|
bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
|
|
|
|
return bShaderHasOutdatedParameters;
|
|
}
|
|
|
|
void SetParameters(const FRenderingCompositePassContext& Context)
|
|
{
|
|
const FVertexShaderRHIParamRef ShaderRHI = GetVertexShader();
|
|
|
|
FGlobalShader::SetParameters<FViewUniformShaderParameters>(Context.RHICmdList, ShaderRHI, Context.View.ViewUniformBuffer);
|
|
|
|
const FPooledRenderTargetDesc* InputDesc = Context.Pass->GetInputDesc(ePId_Input0);
|
|
|
|
if(!InputDesc)
|
|
{
|
|
// input is not hooked up correctly
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
|
|
IMPLEMENT_SHADER_TYPE(,FPostProcessDownsampleVS,TEXT("/Engine/Private/PostProcessDownsample.usf"),TEXT("MainDownsampleVS"),SF_Vertex);
|
|
|
|
/** Encapsulates the post processing down sample compute shader. */
|
|
template <uint32 Method>
|
|
class FPostProcessDownsampleCS : public FGlobalShader
|
|
{
|
|
DECLARE_SHADER_TYPE(FPostProcessDownsampleCS, Global);
|
|
|
|
static bool ShouldCache(EShaderPlatform Platform)
|
|
{
|
|
return IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5);
|
|
}
|
|
|
|
static void ModifyCompilationEnvironment(EShaderPlatform Platform, FShaderCompilerEnvironment& OutEnvironment)
|
|
{
|
|
FGlobalShader::ModifyCompilationEnvironment(Platform,OutEnvironment);
|
|
OutEnvironment.SetDefine(TEXT("METHOD"), Method);
|
|
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEX"), GDownsampleTileSizeX);
|
|
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEY"), GDownsampleTileSizeY);
|
|
}
|
|
|
|
/** Default constructor. */
|
|
FPostProcessDownsampleCS() {}
|
|
|
|
public:
|
|
FPostProcessPassParameters PostprocessParameter;
|
|
FDeferredPixelShaderParameters DeferredParameters;
|
|
FShaderParameter DownsampleComputeParams;
|
|
FShaderParameter OutComputeTex;
|
|
|
|
/** Initialization constructor. */
|
|
FPostProcessDownsampleCS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
|
|
: FGlobalShader(Initializer)
|
|
{
|
|
PostprocessParameter.Bind(Initializer.ParameterMap);
|
|
DeferredParameters.Bind(Initializer.ParameterMap);
|
|
DownsampleComputeParams.Bind(Initializer.ParameterMap, TEXT("DownsampleComputeParams"));
|
|
OutComputeTex.Bind(Initializer.ParameterMap, TEXT("OutComputeTex"));
|
|
}
|
|
|
|
// FShader interface.
|
|
virtual bool Serialize(FArchive& Ar) override
|
|
{
|
|
bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
|
|
Ar << PostprocessParameter << DeferredParameters << DownsampleComputeParams << OutComputeTex;
|
|
return bShaderHasOutdatedParameters;
|
|
}
|
|
|
|
template <typename TRHICmdList>
|
|
void SetParameters(TRHICmdList& RHICmdList, const FRenderingCompositePassContext& Context, const FIntPoint& SrcSize, FUnorderedAccessViewRHIParamRef DestUAV)
|
|
{
|
|
const FComputeShaderRHIParamRef ShaderRHI = GetComputeShader();
|
|
FGlobalShader::SetParameters<FViewUniformShaderParameters>(RHICmdList, ShaderRHI, Context.View.ViewUniformBuffer);
|
|
|
|
// filter only if needed for better performance
|
|
FSamplerStateRHIParamRef Filter = (Method == 2) ?
|
|
TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI():
|
|
TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
|
|
|
PostprocessParameter.SetCS(ShaderRHI, Context, RHICmdList, Filter);
|
|
DeferredParameters.Set(RHICmdList, ShaderRHI, Context.View, MD_PostProcess);
|
|
RHICmdList.SetUAVParameter(ShaderRHI, OutComputeTex.GetBaseIndex(), DestUAV);
|
|
|
|
const float PixelScale = (Method == 2) ? 0.5f : 1.0f;
|
|
FVector4 DownsampleComputeValues(PixelScale / SrcSize.X, PixelScale / SrcSize.Y, 2.f / SrcSize.X, 2.f / SrcSize.Y);
|
|
SetShaderValue(RHICmdList, ShaderRHI, DownsampleComputeParams, DownsampleComputeValues);
|
|
}
|
|
|
|
template <typename TRHICmdList>
|
|
void UnsetParameters(TRHICmdList& RHICmdList)
|
|
{
|
|
const FComputeShaderRHIParamRef ShaderRHI = GetComputeShader();
|
|
RHICmdList.SetUAVParameter(ShaderRHI, OutComputeTex.GetBaseIndex(), NULL);
|
|
}
|
|
};
|
|
|
|
// #define avoids a lot of code duplication
|
|
#define VARIATION1(A) typedef FPostProcessDownsampleCS<A> FPostProcessDownsampleCS##A; \
|
|
IMPLEMENT_SHADER_TYPE(template<>,FPostProcessDownsampleCS##A,TEXT("/Engine/Private/PostProcessDownsample.usf"),TEXT("MainCS"),SF_Compute);
|
|
|
|
VARIATION1(0) VARIATION1(1) VARIATION1(2)
|
|
#undef VARIATION1
|
|
|
|
|
|
FRCPassPostProcessDownsample::FRCPassPostProcessDownsample(EPixelFormat InOverrideFormat, uint32 InQuality, bool bInIsComputePass, const TCHAR *InDebugName)
|
|
: OverrideFormat(InOverrideFormat)
|
|
, Quality(InQuality)
|
|
, DebugName(InDebugName)
|
|
{
|
|
bIsComputePass = bInIsComputePass;
|
|
bPreferAsyncCompute = false;
|
|
}
|
|
|
|
template <uint32 Method>
|
|
void FRCPassPostProcessDownsample::SetShader(const FRenderingCompositePassContext& Context, const FPooledRenderTargetDesc* InputDesc)
|
|
{
|
|
FGraphicsPipelineStateInitializer GraphicsPSOInit;
|
|
Context.RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
|
|
GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI();
|
|
GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI();
|
|
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();
|
|
GraphicsPSOInit.PrimitiveType = PT_TriangleList;
|
|
|
|
auto ShaderMap = Context.GetShaderMap();
|
|
TShaderMapRef<FPostProcessDownsampleVS> VertexShader(ShaderMap);
|
|
TShaderMapRef<FPostProcessDownsamplePS<Method> > PixelShader(ShaderMap);
|
|
|
|
GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI;
|
|
GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader);
|
|
GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader);
|
|
SetGraphicsPipelineState(Context.RHICmdList, GraphicsPSOInit);
|
|
|
|
PixelShader->SetParameters(Context, InputDesc);
|
|
VertexShader->SetParameters(Context);
|
|
}
|
|
|
|
void FRCPassPostProcessDownsample::Process(FRenderingCompositePassContext& Context)
|
|
{
|
|
const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);
|
|
AsyncEndFence = FComputeFenceRHIRef();
|
|
|
|
if (!InputDesc)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const FSceneView& View = Context.View;
|
|
const FSceneViewFamily& ViewFamily = *(View.Family);
|
|
|
|
FIntPoint SrcSize = InputDesc->Extent;
|
|
FIntPoint DestSize = PassOutputs[0].RenderTargetDesc.Extent;
|
|
|
|
// e.g. 4 means the input texture is 4x smaller than the buffer size
|
|
uint32 ScaleFactor = FMath::DivideAndRoundUp(FSceneRenderTargets::Get(Context.RHICmdList).GetBufferSizeXY().Y, SrcSize.Y);
|
|
|
|
FIntRect SrcRect = View.ViewRect / ScaleFactor;
|
|
FIntRect DestRect = FIntRect::DivideAndRoundUp(SrcRect, 2);
|
|
SrcRect = DestRect * 2;
|
|
|
|
SCOPED_DRAW_EVENTF(Context.RHICmdList, Downsample, TEXT("Downsample%s %dx%d"), bIsComputePass?TEXT("Compute"):TEXT(""), DestRect.Width(), DestRect.Height());
|
|
|
|
const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);
|
|
const bool bIsDepthInputAvailable = (GetInputDesc(ePId_Input1) != nullptr);
|
|
|
|
if (bIsComputePass)
|
|
{
|
|
DestRect = {View.ViewRect.Min, View.ViewRect.Min + DestSize};
|
|
|
|
// Common setup
|
|
SetRenderTarget(Context.RHICmdList, nullptr, nullptr);
|
|
Context.SetViewportAndCallRHI(DestRect, 0.0f, 1.0f);
|
|
|
|
static FName AsyncEndFenceName(TEXT("AsyncDownsampleEndFence"));
|
|
AsyncEndFence = Context.RHICmdList.CreateComputeFence(AsyncEndFenceName);
|
|
|
|
if (IsAsyncComputePass())
|
|
{
|
|
// Async path
|
|
FRHIAsyncComputeCommandListImmediate& RHICmdListComputeImmediate = FRHICommandListExecutor::GetImmediateAsyncComputeCommandList();
|
|
{
|
|
SCOPED_COMPUTE_EVENT(RHICmdListComputeImmediate, AsyncDownsample);
|
|
|
|
WaitForInputPassComputeFences(RHICmdListComputeImmediate);
|
|
RHICmdListComputeImmediate.TransitionResource(EResourceTransitionAccess::ERWBarrier, EResourceTransitionPipeline::EGfxToCompute, DestRenderTarget.UAV);
|
|
|
|
if (bIsDepthInputAvailable)
|
|
{
|
|
DispatchCS<2>(RHICmdListComputeImmediate, Context, SrcSize, DestRect, DestRenderTarget.UAV);
|
|
}
|
|
else if (Quality == 0)
|
|
{
|
|
DispatchCS<0>(RHICmdListComputeImmediate, Context, SrcSize, DestRect, DestRenderTarget.UAV);
|
|
}
|
|
else
|
|
{
|
|
DispatchCS<1>(RHICmdListComputeImmediate, Context, SrcSize, DestRect, DestRenderTarget.UAV);
|
|
}
|
|
|
|
RHICmdListComputeImmediate.TransitionResource(EResourceTransitionAccess::EReadable, EResourceTransitionPipeline::EComputeToGfx, DestRenderTarget.UAV, AsyncEndFence);
|
|
}
|
|
FRHIAsyncComputeCommandListImmediate::ImmediateDispatch(RHICmdListComputeImmediate);
|
|
}
|
|
else
|
|
{
|
|
// Direct path
|
|
WaitForInputPassComputeFences(Context.RHICmdList);
|
|
Context.RHICmdList.TransitionResource(EResourceTransitionAccess::ERWBarrier, EResourceTransitionPipeline::EGfxToCompute, DestRenderTarget.UAV);
|
|
|
|
if (bIsDepthInputAvailable)
|
|
{
|
|
DispatchCS<2>(Context.RHICmdList, Context, SrcSize, DestRect, DestRenderTarget.UAV);
|
|
}
|
|
else if (Quality == 0)
|
|
{
|
|
DispatchCS<0>(Context.RHICmdList, Context, SrcSize, DestRect, DestRenderTarget.UAV);
|
|
}
|
|
else
|
|
{
|
|
DispatchCS<1>(Context.RHICmdList, Context, SrcSize, DestRect, DestRenderTarget.UAV);
|
|
}
|
|
|
|
Context.RHICmdList.TransitionResource(EResourceTransitionAccess::EReadable, EResourceTransitionPipeline::EComputeToGfx, DestRenderTarget.UAV, AsyncEndFence);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// check if we have to clear the whole surface.
|
|
// Otherwise perform the clear when the dest rectangle has been computed.
|
|
auto FeatureLevel = Context.View.GetFeatureLevel();
|
|
if (FeatureLevel == ERHIFeatureLevel::ES2 || FeatureLevel == ERHIFeatureLevel::ES3_1)
|
|
{
|
|
// Set the view family's render target/viewport.
|
|
SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef(), ESimpleRenderTargetMode::EClearColorAndDepth);
|
|
Context.SetViewportAndCallRHI(0, 0, 0.0f, DestSize.X, DestSize.Y, 1.0f);
|
|
}
|
|
else
|
|
{
|
|
// Set the view family's render target/viewport.
|
|
SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef(), ESimpleRenderTargetMode::EExistingColorAndDepth);
|
|
Context.SetViewportAndCallRHI(0, 0, 0.0f, DestSize.X, DestSize.Y, 1.0f);
|
|
DrawClearQuad(Context.RHICmdList, true, FLinearColor(0, 0, 0, 0), false, 1.0f, false, 0, DestSize, DestRect);
|
|
}
|
|
|
|
// InflateSize increases the size of the source/dest rectangle to compensate for bilinear reads and UIBlur pass requirements.
|
|
int32 InflateSize;
|
|
// if second input is hooked up
|
|
if (bIsDepthInputAvailable)
|
|
{
|
|
// also put depth in alpha
|
|
InflateSize = 2;
|
|
SetShader<2>(Context, InputDesc);
|
|
}
|
|
else
|
|
{
|
|
if (Quality == 0)
|
|
{
|
|
SetShader<0>(Context, InputDesc);
|
|
InflateSize = 1;
|
|
}
|
|
else
|
|
{
|
|
SetShader<1>(Context, InputDesc);
|
|
InflateSize = 2;
|
|
}
|
|
}
|
|
|
|
TShaderMapRef<FPostProcessDownsampleVS> VertexShader(Context.GetShaderMap());
|
|
|
|
DrawPostProcessPass(
|
|
Context.RHICmdList,
|
|
DestRect.Min.X, DestRect.Min.Y,
|
|
DestRect.Width(), DestRect.Height(),
|
|
SrcRect.Min.X, SrcRect.Min.Y,
|
|
SrcRect.Width(), SrcRect.Height(),
|
|
DestSize,
|
|
SrcSize,
|
|
*VertexShader,
|
|
View.StereoPass,
|
|
false, // This pass is input for passes that can't use the hmd mask, so we need to disable it to ensure valid input data
|
|
EDRF_UseTriangleOptimization);
|
|
|
|
Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
|
|
}
|
|
}
|
|
|
|
template <uint32 Method, typename TRHICmdList>
|
|
void FRCPassPostProcessDownsample::DispatchCS(TRHICmdList& RHICmdList, FRenderingCompositePassContext& Context, const FIntPoint& SrcSize, const FIntRect& DestRect, FUnorderedAccessViewRHIParamRef DestUAV)
|
|
{
|
|
auto ShaderMap = Context.GetShaderMap();
|
|
TShaderMapRef<FPostProcessDownsampleCS<Method>> ComputeShader(ShaderMap);
|
|
RHICmdList.SetComputeShader(ComputeShader->GetComputeShader());
|
|
|
|
ComputeShader->SetParameters(RHICmdList, Context, SrcSize, DestUAV);
|
|
|
|
uint32 GroupSizeX = FMath::DivideAndRoundUp(DestRect.Width(), GDownsampleTileSizeX);
|
|
uint32 GroupSizeY = FMath::DivideAndRoundUp(DestRect.Height(), GDownsampleTileSizeY);
|
|
DispatchComputeShader(RHICmdList, *ComputeShader, GroupSizeX, GroupSizeY, 1);
|
|
|
|
ComputeShader->UnsetParameters(RHICmdList);
|
|
}
|
|
|
|
FPooledRenderTargetDesc FRCPassPostProcessDownsample::ComputeOutputDesc(EPassOutputId InPassOutputId) const
|
|
{
|
|
FPooledRenderTargetDesc Ret = GetInput(ePId_Input0)->GetOutput()->RenderTargetDesc;
|
|
|
|
Ret.Reset();
|
|
|
|
Ret.Extent = FIntPoint::DivideAndRoundUp(Ret.Extent, 2);
|
|
|
|
Ret.Extent.X = FMath::Max(1, Ret.Extent.X);
|
|
Ret.Extent.Y = FMath::Max(1, Ret.Extent.Y);
|
|
|
|
if(OverrideFormat != PF_Unknown)
|
|
{
|
|
Ret.Format = OverrideFormat;
|
|
}
|
|
|
|
Ret.TargetableFlags &= ~(TexCreate_RenderTargetable | TexCreate_UAV);
|
|
Ret.TargetableFlags |= bIsComputePass ? TexCreate_UAV : TexCreate_RenderTargetable;
|
|
Ret.Flags |= GFastVRamConfig.Downsample;
|
|
Ret.AutoWritable = false;
|
|
Ret.DebugName = DebugName;
|
|
|
|
Ret.ClearValue = FClearValueBinding(FLinearColor(0,0,0,0));
|
|
|
|
return Ret;
|
|
}
|