-
Notifications
You must be signed in to change notification settings - Fork 57
/
FilterGradientsPass.cpp
105 lines (83 loc) · 3.47 KB
/
FilterGradientsPass.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
/***************************************************************************
# 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 "FilterGradientsPass.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;
static const int c_NumFilterPasses = 4;
FilterGradientsPass::FilterGradientsPass(
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_UAV(0),
nvrhi::BindingLayoutItem::PushConstants(0, sizeof(FilterGradientsConstants))
};
m_BindingLayout = m_Device->createBindingLayout(bindingLayoutDesc);
}
void FilterGradientsPass::CreatePipeline()
{
donut::log::debug("Initializing FilterGradientsPass...");
m_ComputeShader = m_ShaderFactory->CreateShader("app/FilterGradientsPass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute);
nvrhi::ComputePipelineDesc pipelineDesc;
pipelineDesc.bindingLayouts = { m_BindingLayout };
pipelineDesc.CS = m_ComputeShader;
m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc);
}
void FilterGradientsPass::CreateBindingSet(const RenderTargets& renderTargets)
{
nvrhi::BindingSetDesc bindingSetDesc;
bindingSetDesc.bindings = {
nvrhi::BindingSetItem::Texture_UAV(0, renderTargets.Gradients),
nvrhi::BindingSetItem::PushConstants(0, sizeof(FilterGradientsConstants))
};
m_BindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout);
m_GradientsTexture = renderTargets.Gradients;
}
void FilterGradientsPass::Render(
nvrhi::ICommandList* commandList,
const donut::engine::IView& view,
bool checkerboard)
{
commandList->beginMarker("Filter Gradients");
FilterGradientsConstants constants = {};
constants.viewportSize = dm::uint2(view.GetViewExtent().width(), view.GetViewExtent().height());
if (checkerboard) constants.viewportSize.x /= 2;
constants.checkerboard = checkerboard;
nvrhi::ComputeState state;
state.bindings = { m_BindingSet };
state.pipeline = m_ComputePipeline;
commandList->setComputeState(state);
for (int passIndex = 0; passIndex < c_NumFilterPasses; passIndex++)
{
constants.passIndex = passIndex;
commandList->setPushConstants(&constants, sizeof(constants));
commandList->dispatch(
dm::div_ceil(view.GetViewExtent().width(), 8),
dm::div_ceil(view.GetViewExtent().height(), 8),
1);
nvrhi::utils::TextureUavBarrier(commandList, m_GradientsTexture);
commandList->commitBarriers();
}
commandList->endMarker();
}
int FilterGradientsPass::GetOutputBufferIndex()
{
return c_NumFilterPasses & 1;
}