-
Notifications
You must be signed in to change notification settings - Fork 59
/
Copy pathAccumulationPass.cpp
109 lines (85 loc) · 3.87 KB
/
AccumulationPass.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/***************************************************************************
# Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto. Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
**************************************************************************/
#include "AccumulationPass.h"
#include "RenderTargets.h"
#include <donut/engine/ShaderFactory.h>
#include <donut/engine/View.h>
#include <donut/core/log.h>
#include <nvrhi/utils.h>
using namespace donut::math;
#include "../shaders/ShaderParameters.h"
using namespace donut::engine;
AccumulationPass::AccumulationPass(
nvrhi::IDevice* device,
std::shared_ptr<ShaderFactory> shaderFactory)
: m_Device(device)
, m_ShaderFactory(shaderFactory)
{
nvrhi::BindingLayoutDesc bindingLayoutDesc;
bindingLayoutDesc.visibility = nvrhi::ShaderType::Compute;
bindingLayoutDesc.bindings = {
nvrhi::BindingLayoutItem::Texture_SRV(0),
nvrhi::BindingLayoutItem::Texture_UAV(0),
nvrhi::BindingLayoutItem::Sampler(0),
nvrhi::BindingLayoutItem::PushConstants(0, sizeof(AccumulationConstants))
};
m_BindingLayout = m_Device->createBindingLayout(bindingLayoutDesc);
auto samplerDesc = nvrhi::SamplerDesc()
.setAllFilters(true);
m_Sampler = m_Device->createSampler(samplerDesc);
}
void AccumulationPass::CreatePipeline()
{
donut::log::debug("Initializing AccumulationPass...");
m_ComputeShader = m_ShaderFactory->CreateShader("app/AccumulationPass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute);
nvrhi::ComputePipelineDesc pipelineDesc;
pipelineDesc.bindingLayouts = { m_BindingLayout };
pipelineDesc.CS = m_ComputeShader;
m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc);
}
void AccumulationPass::CreateBindingSet(const RenderTargets& renderTargets)
{
nvrhi::BindingSetDesc bindingSetDesc;
bindingSetDesc.bindings = {
nvrhi::BindingSetItem::Texture_SRV(0, renderTargets.HdrColor),
nvrhi::BindingSetItem::Texture_UAV(0, renderTargets.AccumulatedColor),
nvrhi::BindingSetItem::Sampler(0, m_Sampler),
nvrhi::BindingSetItem::PushConstants(0, sizeof(AccumulationConstants))
};
m_BindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout);
m_CompositedColor = renderTargets.HdrColor;
}
void AccumulationPass::Render(
nvrhi::ICommandList* commandList,
const donut::engine::IView& sourceView,
const donut::engine::IView& upscaledView,
float accumulationWeight)
{
commandList->beginMarker("Accumulation");
const auto sourceViewport = sourceView.GetViewportState().viewports[0];
const auto upscaledViewport = upscaledView.GetViewportState().viewports[0];
const auto& inputDesc = m_CompositedColor->getDesc();
AccumulationConstants constants = {};
constants.inputSize = float2(sourceViewport.width(), sourceViewport.height());
constants.inputTextureSizeInv = float2(1.f / float(inputDesc.width), 1.f / float(inputDesc.height));
constants.outputSize = float2(upscaledViewport.width(), upscaledViewport.height());
constants.pixelOffset = sourceView.GetPixelOffset();
constants.blendFactor = accumulationWeight;
nvrhi::ComputeState state;
state.bindings = { m_BindingSet };
state.pipeline = m_ComputePipeline;
commandList->setComputeState(state);
commandList->setPushConstants(&constants, sizeof(constants));
commandList->dispatch(
dm::div_ceil(upscaledView.GetViewExtent().width(), 8),
dm::div_ceil(upscaledView.GetViewExtent().height(), 8),
1);
commandList->endMarker();
}