• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "render_post_process_dof_node.h"
17 
18 #include <base/containers/fixed_string.h>
19 #include <base/containers/unordered_map.h>
20 #include <base/math/vector.h>
21 #include <core/plugin/intf_class_factory.h>
22 #include <core/property/property_types.h>
23 #include <core/property_tools/property_api_impl.inl>
24 #include <render/datastore/intf_render_data_store_manager.h>
25 #include <render/datastore/intf_render_data_store_pod.h>
26 #include <render/datastore/render_data_store_render_pods.h>
27 #include <render/device/intf_gpu_resource_manager.h>
28 #include <render/device/intf_shader_manager.h>
29 #include <render/intf_render_context.h>
30 #include <render/namespace.h>
31 #include <render/nodecontext/intf_node_context_descriptor_set_manager.h>
32 #include <render/nodecontext/intf_node_context_pso_manager.h>
33 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
34 #include <render/nodecontext/intf_render_command_list.h>
35 #include <render/nodecontext/intf_render_node_context_manager.h>
36 #include <render/nodecontext/intf_render_node_util.h>
37 #include <render/property/property_types.h>
38 
39 #include "datastore/render_data_store_pod.h"
40 #include "datastore/render_data_store_post_process.h"
41 #include "default_engine_constants.h"
42 #include "device/gpu_resource_handle_util.h"
43 #include "postprocesses/render_post_process_blur.h"
44 #include "render_post_process_dof.h"
45 #include "util/log.h"
46 
47 // shaders
48 #include <render/shaders/common/render_post_process_structs_common.h>
49 
50 using namespace BASE_NS;
51 using namespace CORE_NS;
52 using namespace RENDER_NS;
53 
54 CORE_BEGIN_NAMESPACE()
55 DATA_TYPE_METADATA(
56     RenderPostProcessDofNode::NodeInputs, MEMBER_PROPERTY(input, "input", 0), MEMBER_PROPERTY(depth, "depth", 0))
57 DATA_TYPE_METADATA(RenderPostProcessDofNode::NodeOutputs, MEMBER_PROPERTY(output, "output", 0))
58 CORE_END_NAMESPACE()
59 
60 RENDER_BEGIN_NAMESPACE()
61 namespace {
62 constexpr DynamicStateEnum DYNAMIC_STATES[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR };
63 constexpr string_view DOF_BLUR_SHADER_NAME = "rendershaders://shader/depth_of_field_blur.shader";
64 constexpr string_view DOF_SHADER_NAME = "rendershaders://shader/depth_of_field.shader";
65 constexpr int32_t BUFFER_SIZE_IN_BYTES = sizeof(RenderPostProcessDofNode::DofConfig);
66 constexpr GpuBufferDesc UBO_DESC { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
67     (CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT | CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT),
68     CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, 0U };
69 
CreateGpuBuffers(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderHandleReference & handle)70 RenderHandleReference CreateGpuBuffers(
71     IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderHandleReference& handle)
72 {
73     // Create buffer for the shader data.
74     GpuBufferDesc desc = UBO_DESC;
75     desc.byteSize = BUFFER_SIZE_IN_BYTES;
76     return gpuResourceMgr.Create(handle, desc);
77 }
78 
UpdateBuffer(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderHandle & handle,const RenderPostProcessDofNode::DofConfig & shaderParameters)79 void UpdateBuffer(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderHandle& handle,
80     const RenderPostProcessDofNode::DofConfig& shaderParameters)
81 {
82     if (void* data = gpuResourceMgr.MapBuffer(handle); data) {
83         CloneData(data, sizeof(RenderPostProcessDofNode::DofConfig), &shaderParameters,
84             sizeof(RenderPostProcessDofNode::DofConfig));
85         gpuResourceMgr.UnmapBuffer(handle);
86     }
87 }
88 } // namespace
89 
RenderPostProcessDofNode()90 RenderPostProcessDofNode::RenderPostProcessDofNode()
91     : inputProperties_(
92           &nodeInputsData, array_view(PropertyType::DataType<RenderPostProcessDofNode::NodeInputs>::properties)),
93       outputProperties_(
94           &nodeOutputsData, array_view(PropertyType::DataType<RenderPostProcessDofNode::NodeOutputs>::properties))
95 
96 {}
97 
GetRenderInputProperties()98 IPropertyHandle* RenderPostProcessDofNode::GetRenderInputProperties()
99 {
100     return inputProperties_.GetData();
101 }
102 
GetRenderOutputProperties()103 IPropertyHandle* RenderPostProcessDofNode::GetRenderOutputProperties()
104 {
105     return outputProperties_.GetData();
106 }
107 
SetRenderAreaRequest(const RenderAreaRequest & renderAreaRequest)108 void RenderPostProcessDofNode::SetRenderAreaRequest(const RenderAreaRequest& renderAreaRequest)
109 {
110     useRequestedRenderArea_ = true;
111     renderAreaRequest_ = renderAreaRequest;
112 }
113 
GetExecuteFlags() const114 IRenderNode::ExecuteFlags RenderPostProcessDofNode::GetExecuteFlags() const
115 {
116     if (effectProperties_.enabled) {
117         return 0;
118     } else {
119         return IRenderNode::ExecuteFlagBits::EXECUTE_FLAG_BITS_DO_NOT_EXECUTE;
120     }
121 }
122 
Init(const IRenderPostProcess::Ptr & postProcess,IRenderNodeContextManager & renderNodeContextMgr)123 void RenderPostProcessDofNode::Init(
124     const IRenderPostProcess::Ptr& postProcess, IRenderNodeContextManager& renderNodeContextMgr)
125 {
126     renderNodeContextMgr_ = &renderNodeContextMgr;
127     postProcess_ = postProcess;
128 
129     auto* renderClassFactory = renderNodeContextMgr_->GetRenderContext().GetInterface<IClassFactory>();
130     if (renderClassFactory) {
131         auto CreatePostProcessInterface = [&](const auto uid, auto& pp, auto& ppNode) {
132             if (pp = CreateInstance<IRenderPostProcess>(*renderClassFactory, uid); pp) {
133                 ppNode = CreateInstance<IRenderPostProcessNode>(*renderClassFactory, pp->GetRenderPostProcessNodeUid());
134             }
135         };
136 
137         CreatePostProcessInterface(
138             RenderPostProcessBlur::UID, ppRenderBlurInterface_.postProcess, ppRenderBlurInterface_.postProcessNode);
139 
140         CreatePostProcessInterface(RenderPostProcessBlur::UID, ppRenderNearBlurInterface_.postProcess,
141             ppRenderNearBlurInterface_.postProcessNode);
142         CreatePostProcessInterface(RenderPostProcessBlur::UID, ppRenderFarBlurInterface_.postProcess,
143             ppRenderFarBlurInterface_.postProcessNode);
144     }
145 
146     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
147     samplers_.nearest =
148         gpuResourceMgr.GetSamplerHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_NEAREST_CLAMP);
149     samplers_.mipLinear =
150         gpuResourceMgr.GetSamplerHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_MIPMAP_CLAMP);
151     gpuBuffer_ = CreateGpuBuffers(gpuResourceMgr, gpuBuffer_);
152 
153     const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
154     dofShaderData_ = shaderMgr.GetShaderDataByShaderName(DOF_SHADER_NAME);
155     dofBlurShaderData_ = shaderMgr.GetShaderDataByShaderName(DOF_BLUR_SHADER_NAME);
156 
157     const IRenderNodeUtil& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
158     RENDER_NS::DescriptorCounts blurDescriptorCounts =
159         renderNodeUtil.GetDescriptorCounts(dofBlurShaderData_.pipelineLayoutData);
160     descriptorCounts_ = renderNodeUtil.GetDescriptorCounts(dofShaderData_.pipelineLayoutData);
161     descriptorCounts_.counts.insert(
162         descriptorCounts_.counts.end(), blurDescriptorCounts.counts.begin(), blurDescriptorCounts.counts.end());
163     descriptorCounts_.counts.insert(descriptorCounts_.counts.end(),
164         ppRenderNearBlurInterface_.postProcessNode->GetRenderDescriptorCounts().counts.begin(),
165         ppRenderNearBlurInterface_.postProcessNode->GetRenderDescriptorCounts().counts.end());
166     descriptorCounts_.counts.insert(descriptorCounts_.counts.end(),
167         ppRenderFarBlurInterface_.postProcessNode->GetRenderDescriptorCounts().counts.begin(),
168         ppRenderFarBlurInterface_.postProcessNode->GetRenderDescriptorCounts().counts.end());
169 
170     if (ppRenderNearBlurInterface_.postProcessNode) {
171         RenderPostProcessBlur& pp = static_cast<RenderPostProcessBlur&>(*ppRenderNearBlurInterface_.postProcess);
172         pp.propertiesData.blurShaderType =
173             RenderPostProcessBlurNode::BlurShaderType::BLUR_SHADER_TYPE_RGBA_ALPHA_WEIGHT;
174         ppRenderNearBlurInterface_.postProcessNode->Init(
175             ppRenderNearBlurInterface_.postProcess, *renderNodeContextMgr_);
176     }
177     if (ppRenderFarBlurInterface_.postProcessNode) {
178         RenderPostProcessBlur& pp = static_cast<RenderPostProcessBlur&>(*ppRenderFarBlurInterface_.postProcess);
179         pp.propertiesData.blurShaderType =
180             RenderPostProcessBlurNode::BlurShaderType::BLUR_SHADER_TYPE_RGBA_ALPHA_WEIGHT;
181         ppRenderFarBlurInterface_.postProcessNode->Init(ppRenderFarBlurInterface_.postProcess, *renderNodeContextMgr_);
182     }
183 
184     valid_ = true;
185 }
186 
PreExecute()187 void RenderPostProcessDofNode::PreExecute()
188 {
189     if (valid_ && postProcess_ &&
190         (ppRenderNearBlurInterface_.postProcessNode && ppRenderFarBlurInterface_.postProcessNode)) {
191         const array_view<const uint8_t> propertyView = postProcess_->GetData();
192         // this node is directly dependant
193         PLUGIN_ASSERT(propertyView.size_bytes() == sizeof(RenderPostProcessDofNode::EffectProperties));
194         if (propertyView.size_bytes() == sizeof(RenderPostProcessDofNode::EffectProperties)) {
195             effectProperties_ = (const RenderPostProcessDofNode::EffectProperties&)(*propertyView.data());
196         }
197     } else {
198         effectProperties_.enabled = false;
199     }
200 
201     if (ppRenderNearBlurInterface_.postProcessNode && ppRenderNearBlurInterface_.postProcess) {
202         // copy properties to new property post process
203         RenderPostProcessBlur& pp = static_cast<RenderPostProcessBlur&>(*ppRenderNearBlurInterface_.postProcess);
204         pp.propertiesData.enabled = true;
205 
206         RenderPostProcessBlurNode& ppNode =
207             static_cast<RenderPostProcessBlurNode&>(*ppRenderNearBlurInterface_.postProcessNode);
208         ppNode.nodeInputsData.input = effectProperties_.nearMip;
209         ppNode.PreExecute();
210     }
211     if (ppRenderFarBlurInterface_.postProcessNode && ppRenderFarBlurInterface_.postProcess) {
212         // copy properties to new property post process
213         RenderPostProcessBlur& pp = static_cast<RenderPostProcessBlur&>(*ppRenderFarBlurInterface_.postProcess);
214         pp.propertiesData.enabled = true;
215 
216         RenderPostProcessBlurNode& ppNode =
217             static_cast<RenderPostProcessBlurNode&>(*ppRenderFarBlurInterface_.postProcessNode);
218         ppNode.nodeInputsData.input = effectProperties_.farMip;
219         ppNode.PreExecute();
220     }
221 }
222 
CreateRenderPass(const RenderHandle input)223 RenderPass RenderPostProcessDofNode::CreateRenderPass(const RenderHandle input)
224 {
225     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
226     const GpuImageDesc desc = gpuResourceMgr.GetImageDescriptor(input);
227     RenderPass rp;
228     rp.renderPassDesc.attachmentCount = 1u;
229     rp.renderPassDesc.attachmentHandles[0u] = input;
230     rp.renderPassDesc.attachments[0u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
231     rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
232     rp.renderPassDesc.renderArea = { 0, 0, desc.width, desc.height };
233 
234     rp.renderPassDesc.subpassCount = 1u;
235     rp.subpassDesc.colorAttachmentCount = 1u;
236     rp.subpassDesc.colorAttachmentIndices[0u] = 0u;
237     rp.subpassStartIndex = 0u;
238     return rp;
239 }
240 
GetFactorDof() const241 BASE_NS::Math::Vec4 RenderPostProcessDofNode::GetFactorDof() const
242 {
243     const float focusStart =
244         (effectProperties_.dofConfiguration.focusPoint - (effectProperties_.dofConfiguration.focusRange / 2));
245     const float focusEnd =
246         (effectProperties_.dofConfiguration.focusPoint + (effectProperties_.dofConfiguration.focusRange / 2));
247     const float nearTransitionStart = (focusStart - effectProperties_.dofConfiguration.nearTransitionRange);
248     const float farTransitionEnd = (focusEnd + effectProperties_.dofConfiguration.farTransitionRange);
249 
250     return { nearTransitionStart, focusStart, focusEnd, farTransitionEnd };
251 }
252 
GetFactorDof2() const253 BASE_NS::Math::Vec4 RenderPostProcessDofNode::GetFactorDof2() const
254 {
255     return { effectProperties_.dofConfiguration.nearBlur, effectProperties_.dofConfiguration.farBlur,
256         effectProperties_.dofConfiguration.nearPlane, effectProperties_.dofConfiguration.farPlane };
257 }
258 
Execute(IRenderCommandList & cmdList)259 void RenderPostProcessDofNode::Execute(IRenderCommandList& cmdList)
260 {
261     RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderDoF", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
262 
263     CheckDescriptorSetNeed();
264 
265     // NOTE: updates set 0 for dof
266     ExecuteDofBlur(cmdList);
267 
268     auto renderPass = CreateRenderPass(nodeOutputsData.output.handle);
269     if (!RenderHandleUtil::IsValid(psos_.dofPso)) {
270         auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
271         const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
272         const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(dofShaderData_.shader);
273         psos_.dofPso = psoMgr.GetGraphicsPsoHandle(dofShaderData_.shader, gfxHandle, dofShaderData_.pipelineLayout, {},
274             {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
275     }
276 
277     cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
278     cmdList.BindPipeline(psos_.dofPso);
279 
280     {
281         auto& binder = *binders_.dofBinder;
282         binder.ClearBindings();
283         uint32_t binding = 0u;
284         BindableImage input = nodeInputsData.input;
285         input.samplerHandle = samplers_.mipLinear;
286         binder.BindImage(binding, input);
287         binder.BindImage(++binding, effectProperties_.mipImages[0U].GetHandle(), samplers_.mipLinear);
288         binder.BindImage(++binding, effectProperties_.mipImages[1U].GetHandle(), samplers_.mipLinear);
289         BindableImage depth = nodeInputsData.depth;
290         depth.samplerHandle = samplers_.nearest;
291         binder.BindImage(++binding, depth);
292         binder.BindBuffer(++binding, gpuBuffer_.GetHandle(), 0U);
293 
294         cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources());
295         cmdList.BindDescriptorSet(0u, binder.GetDescriptorSetHandle());
296     }
297 
298     if (dofShaderData_.pipelineLayoutData.pushConstant.byteSize > 0U) {
299         const float fWidth = static_cast<float>(renderPass.renderPassDesc.renderArea.extentWidth);
300         const float fHeight = static_cast<float>(renderPass.renderPassDesc.renderArea.extentHeight);
301         const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight }, {} };
302         cmdList.PushConstantData(dofShaderData_.pipelineLayoutData.pushConstant, arrayviewU8(pc));
303     }
304 
305     // dynamic state
306     cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(renderPass));
307     cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(renderPass));
308 
309     cmdList.Draw(3u, 1u, 0u, 0u);
310     cmdList.EndRenderPass();
311 }
312 
ExecuteDofBlur(IRenderCommandList & cmdList)313 void RenderPostProcessDofNode::ExecuteDofBlur(IRenderCommandList& cmdList)
314 {
315     RenderPass rp;
316     {
317         const GpuImageDesc desc = renderNodeContextMgr_->GetGpuResourceManager().GetImageDescriptor(
318             effectProperties_.mipImages[0U].GetHandle());
319         rp.renderPassDesc.attachmentCount = 2u;
320         rp.renderPassDesc.attachmentHandles[0u] = effectProperties_.mipImages[0U].GetHandle();
321         rp.renderPassDesc.attachments[0u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
322         rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
323         rp.renderPassDesc.attachmentHandles[1u] = effectProperties_.mipImages[1U].GetHandle();
324         rp.renderPassDesc.attachments[1u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
325         rp.renderPassDesc.attachments[1u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
326         rp.renderPassDesc.renderArea = { 0, 0, desc.width, desc.height };
327 
328         rp.renderPassDesc.subpassCount = 1u;
329         rp.subpassDesc.colorAttachmentCount = 2u;
330         rp.subpassDesc.colorAttachmentIndices[0u] = 0u;
331         rp.subpassDesc.colorAttachmentIndices[1u] = 1u;
332         rp.subpassStartIndex = 0u;
333     }
334     if (!RenderHandleUtil::IsValid(psos_.dofBlurPso)) {
335         auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
336         const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
337         const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(dofBlurShaderData_.shader);
338         psos_.dofBlurPso = psoMgr.GetGraphicsPsoHandle(dofBlurShaderData_.shader, gfxHandle,
339             dofBlurShaderData_.pipelineLayout, {}, {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
340     }
341     cmdList.BeginRenderPass(rp.renderPassDesc, rp.subpassStartIndex, rp.subpassDesc);
342     cmdList.BindPipeline(psos_.dofBlurPso);
343 
344     shaderParameters_.factors0 = GetFactorDof();
345     shaderParameters_.factors1 = GetFactorDof2();
346 
347     UpdateBuffer(renderNodeContextMgr_->GetGpuResourceManager(), gpuBuffer_.GetHandle(), shaderParameters_);
348 
349     {
350         auto& binder = *binders_.dofBlurBinder;
351         binder.ClearBindings();
352         uint32_t binding = 0u;
353         BindableImage input = nodeInputsData.input;
354         input.samplerHandle = samplers_.mipLinear;
355         binder.BindImage(binding, input);
356         BindableImage depth = nodeInputsData.depth;
357         depth.samplerHandle = samplers_.nearest;
358         binder.BindImage(++binding, depth);
359         binder.BindBuffer(++binding, gpuBuffer_.GetHandle(), 0u);
360 
361         cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources());
362         cmdList.BindDescriptorSet(0U, binder.GetDescriptorSetHandle());
363     }
364 
365     {
366         const float fWidth = static_cast<float>(rp.renderPassDesc.renderArea.extentWidth);
367         const float fHeight = static_cast<float>(rp.renderPassDesc.renderArea.extentHeight);
368         const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight }, {} };
369         cmdList.PushConstantData(dofBlurShaderData_.pipelineLayoutData.pushConstant, arrayviewU8(pc));
370     }
371 
372     // dynamic state
373     cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(rp));
374     cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(rp));
375 
376     cmdList.Draw(3u, 1u, 0u, 0u);
377     cmdList.EndRenderPass();
378     if (ppRenderNearBlurInterface_.postProcessNode && ppRenderNearBlurInterface_.postProcess) {
379         RenderPostProcessBlur& pp = static_cast<RenderPostProcessBlur&>(*ppRenderNearBlurInterface_.postProcess);
380         pp.propertiesData.blurConfiguration.maxMipLevel =
381             static_cast<uint32_t>(Math::round(effectProperties_.dofConfiguration.nearBlur));
382         ppRenderNearBlurInterface_.postProcessNode->Execute(cmdList);
383     }
384     if (ppRenderFarBlurInterface_.postProcessNode && ppRenderFarBlurInterface_.postProcess) {
385         RenderPostProcessBlur& pp = static_cast<RenderPostProcessBlur&>(*ppRenderFarBlurInterface_.postProcess);
386         pp.propertiesData.blurConfiguration.maxMipLevel =
387             static_cast<uint32_t>(Math::round(effectProperties_.dofConfiguration.farBlur));
388         ppRenderFarBlurInterface_.postProcessNode->Execute(cmdList);
389     }
390 }
391 
CheckDescriptorSetNeed()392 void RenderPostProcessDofNode::CheckDescriptorSetNeed()
393 {
394     if (!binders_.dofBinder) {
395         INodeContextDescriptorSetManager& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
396 
397         binders_.dofBlurBinder = descriptorSetMgr.CreateDescriptorSetBinder(
398             descriptorSetMgr.CreateDescriptorSet(0, dofBlurShaderData_.pipelineLayoutData),
399             dofBlurShaderData_.pipelineLayoutData.descriptorSetLayouts[0].bindings);
400         binders_.dofBinder = descriptorSetMgr.CreateDescriptorSetBinder(
401             descriptorSetMgr.CreateDescriptorSet(0, dofShaderData_.pipelineLayoutData),
402             dofShaderData_.pipelineLayoutData.descriptorSetLayouts[0].bindings);
403     }
404 }
405 
GetRenderDescriptorCounts() const406 DescriptorCounts RenderPostProcessDofNode::GetRenderDescriptorCounts() const
407 {
408     return descriptorCounts_;
409 }
410 
411 RENDER_END_NAMESPACE()
412