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