void Radix008A(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, UniformBuffer_SingleUse);

	if (istride > 1)
	{
		TShaderMapRef<FRadix008A_CS> Radix008A_CS(GetGlobalShaderMap());
		RHISetComputeShader(Radix008A_CS->GetComputeShader());

		Radix008A_CS->SetParameters(UniformBuffer);
		Radix008A_CS->SetParameters(pSRV_Src, pUAV_Dst);

		RHIDispatchComputeShader(grid, 1, 1);

		Radix008A_CS->UnsetParameters();
	}
	else
	{
		TShaderMapRef<FRadix008A_CS2> Radix008A_CS2(GetGlobalShaderMap());
		RHISetComputeShader(Radix008A_CS2->GetComputeShader());

		Radix008A_CS2->SetParameters(UniformBuffer);
		Radix008A_CS2->SetParameters(pSRV_Src, pUAV_Dst);

		RHIDispatchComputeShader(grid, 1, 1);

		Radix008A_CS2->UnsetParameters();
	}
}
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());
}
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();
		});