1 /*
2 * Copyright (c) 2024 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_node_post_process_util.h"
17
18 #include <core/property/property_handle_util.h>
19 #include <render/datastore/intf_render_data_store_manager.h>
20 #include <render/datastore/intf_render_data_store_pod.h>
21 #include <render/datastore/render_data_store_render_pods.h>
22 #include <render/device/intf_gpu_resource_manager.h>
23 #include <render/device/intf_shader_manager.h>
24 #include <render/device/pipeline_state_desc.h>
25 #include <render/intf_render_context.h>
26 #include <render/namespace.h>
27 #include <render/nodecontext/intf_node_context_descriptor_set_manager.h>
28 #include <render/nodecontext/intf_node_context_pso_manager.h>
29 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
30 #include <render/nodecontext/intf_render_command_list.h>
31 #include <render/nodecontext/intf_render_node.h>
32 #include <render/nodecontext/intf_render_node_context_manager.h>
33 #include <render/nodecontext/intf_render_node_graph_share_manager.h>
34 #include <render/nodecontext/intf_render_node_parser_util.h>
35 #include <render/nodecontext/intf_render_node_util.h>
36 #include <render/property/property_types.h>
37
38 #include "datastore/render_data_store_pod.h"
39 #include "datastore/render_data_store_post_process.h"
40 #include "default_engine_constants.h"
41 #include "device/gpu_resource_handle_util.h"
42 #include "nodecontext/pipeline_descriptor_set_binder.h"
43 #include "postprocesses/render_post_process_flare.h"
44 #include "util/log.h"
45
46 // shaders
47 #include <render/shaders/common/render_post_process_layout_common.h>
48 #include <render/shaders/common/render_post_process_structs_common.h>
49
50 using namespace BASE_NS;
51 using namespace CORE_NS;
52
53 RENDER_BEGIN_NAMESPACE()
54 namespace {
55 constexpr DynamicStateEnum DYNAMIC_STATES[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR };
56
57 constexpr uint32_t UBO_OFFSET_ALIGNMENT { PipelineLayoutConstants::MIN_UBO_BIND_OFFSET_ALIGNMENT_BYTE_SIZE };
58 constexpr uint32_t MAX_POST_PROCESS_EFFECT_COUNT { 8 };
59 constexpr uint32_t POST_PROCESS_UBO_BYTE_SIZE { sizeof(GlobalPostProcessStruct) +
60 sizeof(LocalPostProcessStruct) * MAX_POST_PROCESS_EFFECT_COUNT };
61
62 constexpr uint32_t GL_LAYER_CANNOT_OPT_FLAGS =
63 PostProcessConfiguration::ENABLE_BLOOM_BIT | PostProcessConfiguration::ENABLE_TAA_BIT;
64
65 constexpr string_view INPUT_COLOR = "color";
66 constexpr string_view INPUT_DEPTH = "depth";
67 constexpr string_view INPUT_VELOCITY = "velocity";
68 constexpr string_view INPUT_HISTORY = "history";
69 constexpr string_view INPUT_HISTORY_NEXT = "history_next";
70
71 constexpr string_view COMBINED_SHADER_NAME = "rendershaders://shader/fullscreen_combined_post_process.shader";
72 constexpr string_view COMBINED_LAYER_SHADER_NAME =
73 "rendershaders://shader/fullscreen_combined_post_process_layer.shader";
74 constexpr string_view FXAA_SHADER_NAME = "rendershaders://shader/fullscreen_fxaa.shader";
75 constexpr string_view TAA_SHADER_NAME = "rendershaders://shader/fullscreen_taa.shader";
76 constexpr string_view DOF_BLUR_SHADER_NAME = "rendershaders://shader/depth_of_field_blur.shader";
77 constexpr string_view DOF_SHADER_NAME = "rendershaders://shader/depth_of_field.shader";
78 constexpr string_view COPY_SHADER_NAME = "rendershaders://shader/fullscreen_copy.shader";
79
CreateRenderPass(const IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderHandle input)80 RenderPass CreateRenderPass(const IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderHandle input)
81 {
82 const GpuImageDesc desc = gpuResourceMgr.GetImageDescriptor(input);
83 RenderPass rp;
84 rp.renderPassDesc.attachmentCount = 1u;
85 rp.renderPassDesc.attachmentHandles[0u] = input;
86 rp.renderPassDesc.attachments[0u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
87 rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
88 rp.renderPassDesc.renderArea = { 0, 0, desc.width, desc.height };
89
90 rp.renderPassDesc.subpassCount = 1u;
91 rp.subpassDesc.colorAttachmentCount = 1u;
92 rp.subpassDesc.colorAttachmentIndices[0u] = 0u;
93 rp.subpassStartIndex = 0u;
94 return rp;
95 }
96
CreatePostProcessDataUniformBuffer(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderHandleReference & handle)97 RenderHandleReference CreatePostProcessDataUniformBuffer(
98 IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderHandleReference& handle)
99 {
100 PLUGIN_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == sizeof(RenderPostProcessConfiguration));
101 PLUGIN_STATIC_ASSERT(sizeof(LocalPostProcessStruct) == UBO_OFFSET_ALIGNMENT);
102 return gpuResourceMgr.Create(
103 handle, GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
104 (CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT | CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT),
105 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, POST_PROCESS_UBO_BYTE_SIZE });
106 }
107
FillTmpImageDesc(GpuImageDesc & desc)108 void FillTmpImageDesc(GpuImageDesc& desc)
109 {
110 desc.imageType = CORE_IMAGE_TYPE_2D;
111 desc.imageViewType = CORE_IMAGE_VIEW_TYPE_2D;
112 desc.engineCreationFlags = EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS |
113 EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS;
114 desc.usageFlags =
115 ImageUsageFlagBits::CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | ImageUsageFlagBits::CORE_IMAGE_USAGE_SAMPLED_BIT;
116 // don't want this multisampled even if the final output would be.
117 desc.sampleCountFlags = SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT;
118 desc.layerCount = 1U;
119 desc.mipCount = 1U;
120 }
121
IsValidHandle(const BindableImage & img)122 inline bool IsValidHandle(const BindableImage& img)
123 {
124 return RenderHandleUtil::IsValid(img.handle);
125 }
126 } // namespace
127
Init(IRenderNodeContextManager & renderNodeContextMgr,const IRenderNodePostProcessUtil::PostProcessInfo & postProcessInfo)128 void RenderNodePostProcessUtil::Init(
129 IRenderNodeContextManager& renderNodeContextMgr, const IRenderNodePostProcessUtil::PostProcessInfo& postProcessInfo)
130 {
131 renderNodeContextMgr_ = &renderNodeContextMgr;
132 postProcessInfo_ = postProcessInfo;
133 CreatePostProcessInterfaces();
134 ParseRenderNodeInputs();
135 UpdateImageData();
136
137 deviceBackendType_ = renderNodeContextMgr_->GetRenderContext().GetDevice().GetBackendType();
138
139 auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
140 const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
141 samplers_.nearest =
142 gpuResourceMgr.GetSamplerHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_NEAREST_CLAMP);
143 samplers_.linear =
144 gpuResourceMgr.GetSamplerHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_CLAMP);
145 samplers_.mipLinear =
146 gpuResourceMgr.GetSamplerHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_MIPMAP_CLAMP);
147 ubos_.postProcess = CreatePostProcessDataUniformBuffer(gpuResourceMgr, ubos_.postProcess);
148
149 InitCreateShaderResources();
150
151 if ((!IsValidHandle(images_.input)) || (!IsValidHandle(images_.output))) {
152 validInputs_ = false;
153 PLUGIN_LOG_E("RN: %s, expects custom input and output image", renderNodeContextMgr_->GetName().data());
154 }
155
156 if (jsonInputs_.renderDataStore.dataStoreName.empty()) {
157 PLUGIN_LOG_W("RenderNodeCombinedPostProcess: render data store configuration not set in render node graph");
158 }
159 if (jsonInputs_.renderDataStore.typeName != RenderDataStorePod::TYPE_NAME) {
160 PLUGIN_LOG_E("RenderNodeCombinedPostProcess: render data store type name not supported (%s != %s)",
161 jsonInputs_.renderDataStore.typeName.data(), RenderDataStorePod::TYPE_NAME);
162 validInputs_ = false;
163 }
164
165 {
166 vector<DescriptorCounts> descriptorCounts;
167 descriptorCounts.reserve(16U);
168 // pre-set custom descriptor sets
169 descriptorCounts.push_back(DescriptorCounts { {
170 { CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 8u },
171 { CORE_DESCRIPTOR_TYPE_SAMPLER, 8u },
172 { CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 8u },
173 } });
174 descriptorCounts.push_back(renderBloom_.GetDescriptorCounts());
175 descriptorCounts.push_back(renderBlur_.GetDescriptorCounts());
176 descriptorCounts.push_back(renderBloom_.GetDescriptorCounts());
177 descriptorCounts.push_back(renderMotionBlur_.GetDescriptorCounts());
178 descriptorCounts.push_back(renderCopy_.GetRenderDescriptorCounts());
179 descriptorCounts.push_back(renderCopyLayer_.GetRenderDescriptorCounts());
180 descriptorCounts.push_back(renderNodeUtil.GetDescriptorCounts(combineData_.sd.pipelineLayoutData));
181 descriptorCounts.push_back(renderNodeUtil.GetDescriptorCounts(combineDataLayer_.sd.pipelineLayoutData));
182 descriptorCounts.push_back(renderNodeUtil.GetDescriptorCounts(fxaaData_.sd.pipelineLayoutData));
183 descriptorCounts.push_back(renderNodeUtil.GetDescriptorCounts(taaData_.sd.pipelineLayoutData));
184 descriptorCounts.push_back(renderNodeUtil.GetDescriptorCounts(dofBlurData_.sd.pipelineLayoutData));
185 descriptorCounts.push_back(renderNearBlur_.GetDescriptorCounts());
186 descriptorCounts.push_back(renderFarBlur_.GetDescriptorCounts());
187 descriptorCounts.push_back(renderNodeUtil.GetDescriptorCounts(dofData_.sd.pipelineLayoutData));
188 descriptorCounts.push_back(renderNodeUtil.GetDescriptorCounts(copyData_.sd.pipelineLayoutData));
189 renderNodeContextMgr.GetDescriptorSetManager().ResetAndReserve(descriptorCounts);
190 }
191 // bloom does not do combine, and does not render to output with this combined post process
192 ProcessPostProcessConfiguration();
193 {
194 const RenderBloom::BloomInfo bloomInfo { images_.input, {}, ubos_.postProcess.GetHandle(),
195 ppConfig_.bloomConfiguration.useCompute };
196 renderBloom_.Init(renderNodeContextMgr, bloomInfo);
197 }
198 {
199 RenderBlur::BlurInfo blurInfo { images_.output, ubos_.postProcess.GetHandle(), false,
200 CORE_BLUR_TYPE_DOWNSCALE_RGBA, CORE_BLUR_TYPE_RGBA_DOF };
201 renderBlur_.Init(renderNodeContextMgr, blurInfo);
202 renderNearBlur_.Init(renderNodeContextMgr, blurInfo);
203 renderFarBlur_.Init(renderNodeContextMgr, blurInfo);
204 }
205 {
206 RenderMotionBlur::MotionBlurInfo motionBlurInfo {};
207 renderMotionBlur_.Init(renderNodeContextMgr, motionBlurInfo);
208 }
209 renderCopy_.Init(renderNodeContextMgr);
210 if (deviceBackendType_ != DeviceBackendType::VULKAN) {
211 // prepare for possible layer copy
212 renderCopyLayer_.Init(renderNodeContextMgr);
213 }
214
215 if (ppLensFlareInterface_.postProcessNode) {
216 ppLensFlareInterface_.postProcessNode->Init(ppLensFlareInterface_.postProcess, *renderNodeContextMgr_);
217 }
218
219 InitCreateBinders();
220
221 if ((!jsonInputs_.resources.customOutputImages.empty()) && (!inputResources_.customOutputImages.empty()) &&
222 (RenderHandleUtil::IsValid(inputResources_.customOutputImages[0].handle))) {
223 IRenderNodeGraphShareManager& shrMgr = renderNodeContextMgr_->GetRenderNodeGraphShareManager();
224 shrMgr.RegisterRenderNodeOutput(
225 jsonInputs_.resources.customOutputImages[0u].name, inputResources_.customOutputImages[0u].handle);
226 }
227 }
228
PreExecute(const IRenderNodePostProcessUtil::PostProcessInfo & postProcessInfo)229 void RenderNodePostProcessUtil::PreExecute(const IRenderNodePostProcessUtil::PostProcessInfo& postProcessInfo)
230 {
231 postProcessInfo_ = postProcessInfo;
232 if (!validInputs_) {
233 return;
234 }
235
236 const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
237 if (jsonInputs_.hasChangeableResourceHandles) {
238 inputResources_ = renderNodeUtil.CreateInputResources(jsonInputs_.resources);
239 }
240 UpdateImageData();
241
242 auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
243 const GpuImageDesc inputDesc = gpuResourceMgr.GetImageDescriptor(images_.input.handle);
244 const GpuImageDesc outputDesc = gpuResourceMgr.GetImageDescriptor(images_.output.handle);
245 outputSize_ = { outputDesc.width, outputDesc.height };
246 #if (RENDER_VALIDATION_ENABLED == 1)
247 if ((ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_TAA_BIT) &&
248 (!validInputsForTaa_)) {
249 PLUGIN_LOG_ONCE_W(renderNodeContextMgr_->GetName() + "_taa_depth_vel",
250 "RENDER_VALIDATION: Default TAA post process needs output depth, velocity, and history.");
251 }
252 if ((ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_DOF_BIT) &&
253 (!validInputsForDof_)) {
254 PLUGIN_LOG_ONCE_W(renderNodeContextMgr_->GetName() + "_dof_depth",
255 "RENDER_VALIDATION: Default DOF post process needs output depth.");
256 }
257 if ((ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_MOTION_BLUR_BIT) &&
258 (!validInputsForMb_)) {
259 PLUGIN_LOG_ONCE_W(renderNodeContextMgr_->GetName() + "_mb_vel",
260 "RENDER_VALIDATION: Default motion blur post process needs output (samplable) velocity.");
261 }
262 #endif
263
264 // process this frame's enabled post processes here
265 // bloom might need target updates, no further processing is needed
266 ProcessPostProcessConfiguration();
267
268 // post process
269 const bool fxaaEnabled =
270 ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_FXAA_BIT;
271 const bool motionBlurEnabled =
272 validInputsForMb_ &&
273 (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_MOTION_BLUR_BIT);
274 const bool dofEnabled =
275 validInputsForDof_ &&
276 (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_DOF_BIT);
277
278 ti_.idx = 0;
279 const bool basicImagesNeeded = fxaaEnabled || motionBlurEnabled || dofEnabled;
280 const bool mipImageNeeded = dofEnabled;
281 const auto nearMips = static_cast<uint32_t>(Math::ceilToInt(ppConfig_.dofConfiguration.nearBlur));
282 const auto farMips = static_cast<uint32_t>(Math::ceilToInt(ppConfig_.dofConfiguration.farBlur));
283 const bool mipCountChanged = (nearMips != ti_.mipCount[0U]) || (farMips != ti_.mipCount[1U]);
284 const bool sizeChanged = (ti_.targetSize.x != static_cast<float>(outputSize_.x)) ||
285 (ti_.targetSize.y != static_cast<float>(outputSize_.y));
286 if (sizeChanged) {
287 ti_.targetSize.x = Math::max(1.0f, static_cast<float>(outputSize_.x));
288 ti_.targetSize.y = Math::max(1.0f, static_cast<float>(outputSize_.y));
289 ti_.targetSize.z = 1.f / ti_.targetSize.x;
290 ti_.targetSize.w = 1.f / ti_.targetSize.y;
291 }
292 if (basicImagesNeeded) {
293 if ((!ti_.images[0U]) || sizeChanged) {
294 #if (RENDER_VALIDATION_ENABLED == 1)
295 PLUGIN_LOG_I("RENDER_VALIDATION: post process temporary images re-created (size:%ux%u)", outputSize_.x,
296 outputSize_.y);
297 #endif
298 GpuImageDesc tmpDesc = outputDesc;
299 FillTmpImageDesc(tmpDesc);
300 ti_.images[0U] = gpuResourceMgr.Create(ti_.images[0U], tmpDesc);
301 ti_.images[1U] = gpuResourceMgr.Create(ti_.images[1U], tmpDesc);
302 ti_.imageCount = 2U;
303 }
304 } else {
305 ti_.images[0U] = {};
306 ti_.images[1U] = {};
307 }
308 if (mipImageNeeded) {
309 if ((!ti_.mipImages[0U]) || sizeChanged || mipCountChanged) {
310 #if (RENDER_VALIDATION_ENABLED == 1)
311 PLUGIN_LOG_I("RENDER_VALIDATION: post process temporary mip image re-created (size:%ux%u)", outputSize_.x,
312 outputSize_.y);
313 #endif
314 GpuImageDesc tmpDesc = outputDesc;
315 FillTmpImageDesc(tmpDesc);
316 tmpDesc.mipCount = nearMips;
317 ti_.mipImages[0] = gpuResourceMgr.Create(ti_.mipImages[0U], tmpDesc);
318 tmpDesc.mipCount = farMips;
319 ti_.mipImages[1] = gpuResourceMgr.Create(ti_.mipImages[1U], tmpDesc);
320 ti_.mipImageCount = 2U;
321 ti_.mipCount[0U] = nearMips;
322 ti_.mipCount[1U] = farMips;
323 }
324 } else {
325 ti_.mipImages[0U] = {};
326 ti_.mipImages[1U] = {};
327 }
328 if ((!basicImagesNeeded) && (!mipImageNeeded)) {
329 ti_ = {};
330 }
331
332 BindableImage postTaaBloomInput = images_.input;
333 // prepare for possible layer copy
334 glOptimizedLayerCopyEnabled_ = false;
335 if ((deviceBackendType_ != DeviceBackendType::VULKAN) &&
336 (images_.input.layer != PipelineStateConstants::GPU_IMAGE_ALL_LAYERS)) {
337 if ((ppConfig_.enableFlags & GL_LAYER_CANNOT_OPT_FLAGS) == 0U) {
338 // optimize with combine
339 glOptimizedLayerCopyEnabled_ = true;
340 } else {
341 if (sizeChanged || (!ti_.layerCopyImage)) {
342 GpuImageDesc tmpDesc = inputDesc; // NOTE: input desc
343 FillTmpImageDesc(tmpDesc);
344 ti_.layerCopyImage = gpuResourceMgr.Create(ti_.layerCopyImage, tmpDesc);
345 }
346
347 BindableImage layerCopyOutput;
348 layerCopyOutput.handle = ti_.layerCopyImage.GetHandle();
349 renderCopyLayer_.PreExecute();
350
351 // postTaa bloom input
352 postTaaBloomInput = layerCopyOutput;
353 }
354 }
355
356 if (validInputsForTaa_ &&
357 (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_TAA_BIT)) {
358 postTaaBloomInput = images_.historyNext;
359 }
360
361 // NOTE: separate flare with new post process interface
362 if (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_LENS_FLARE_BIT) {
363 if (ppLensFlareInterface_.postProcessNode && ppLensFlareInterface_.postProcess) {
364 // copy properties to new property post process
365 IPropertyHandle* props = ppLensFlareInterface_.postProcess->GetProperties();
366 CORE_NS::SetPropertyValue(props, "flarePos", ppConfig_.lensFlareConfiguration.flarePosition);
367 CORE_NS::SetPropertyValue(props, "intensity", ppConfig_.lensFlareConfiguration.intensity);
368
369 auto& ppNode = *ppLensFlareInterface_.postProcessNode;
370 CORE_NS::SetPropertyValue(ppNode.GetRenderInputProperties(), "input", postTaaBloomInput);
371 ppNode.PreExecute();
372 }
373 }
374
375 if (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_BLOOM_BIT) {
376 const RenderBloom::BloomInfo bloomInfo { postTaaBloomInput, {}, ubos_.postProcess.GetHandle(),
377 ppConfig_.bloomConfiguration.useCompute };
378 renderBloom_.PreExecute(*renderNodeContextMgr_, bloomInfo, ppConfig_);
379 }
380
381 // needs to evaluate what is the final effect, where we will use the final target
382 // the final target (output) might a swapchain which cannot be sampled
383 framePostProcessInOut_.clear();
384 // after bloom or TAA
385 BindableImage input = postTaaBloomInput;
386 const bool postProcessNeeded = (ppConfig_.enableFlags != 0);
387 const bool sameInputOutput = (images_.input.handle == images_.output.handle);
388 // combine
389 if (postProcessNeeded && (!sameInputOutput)) {
390 const BindableImage output =
391 (basicImagesNeeded || mipImageNeeded) ? GetIntermediateImage(input.handle) : images_.output;
392 framePostProcessInOut_.push_back({ input, output });
393 input = framePostProcessInOut_.back().output;
394 }
395 if (fxaaEnabled) {
396 framePostProcessInOut_.push_back({ input, GetIntermediateImage(input.handle) });
397 input = framePostProcessInOut_.back().output;
398 }
399 if (motionBlurEnabled) {
400 framePostProcessInOut_.push_back({ input, GetIntermediateImage(input.handle) });
401 input = framePostProcessInOut_.back().output;
402 }
403 if (dofEnabled) {
404 framePostProcessInOut_.push_back({ input, GetIntermediateImage(input.handle) });
405 input = framePostProcessInOut_.back().output;
406 }
407 if (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_BLUR_BIT) {
408 framePostProcessInOut_.push_back({ input, input });
409 input = framePostProcessInOut_.back().output;
410 }
411 // finalize
412 if (!framePostProcessInOut_.empty()) {
413 framePostProcessInOut_.back().output = images_.output;
414 }
415
416 uint32_t ppIdx = 0U;
417 if (postProcessNeeded && (!sameInputOutput)) {
418 ppIdx++;
419 }
420 if (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_FXAA_BIT) {
421 ppIdx++;
422 }
423 if (motionBlurEnabled) {
424 const auto& inOut = framePostProcessInOut_[ppIdx++];
425 const RenderMotionBlur::MotionBlurInfo info { inOut.input.handle, inOut.output.handle, images_.velocity.handle,
426 images_.depth.handle, ubos_.postProcess.GetHandle(),
427 sizeof(GlobalPostProcessStruct) + PP_MB_IDX * UBO_OFFSET_ALIGNMENT, outputSize_ };
428 renderMotionBlur_.PreExecute(*renderNodeContextMgr_, info, ppConfig_);
429 }
430
431 if (dofEnabled) {
432 auto nearMip = GetMipImage(input.handle);
433 RenderBlur::BlurInfo blurInfo { nearMip, ubos_.postProcess.GetHandle(), false, CORE_BLUR_TYPE_DOWNSCALE_RGBA,
434 CORE_BLUR_TYPE_RGBA_DOF };
435 renderNearBlur_.PreExecute(*renderNodeContextMgr_, blurInfo);
436
437 blurInfo.blurTarget = GetMipImage(nearMip.handle);
438 renderFarBlur_.PreExecute(*renderNodeContextMgr_, blurInfo);
439 ppIdx++;
440 }
441
442 if (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_BLUR_BIT) {
443 const auto& inOut = framePostProcessInOut_[ppIdx++];
444 RenderBlur::BlurInfo blurInfo { inOut.output, ubos_.postProcess.GetHandle(), false };
445 renderBlur_.PreExecute(*renderNodeContextMgr_, blurInfo);
446 }
447
448 PLUGIN_ASSERT(ppIdx == framePostProcessInOut_.size());
449
450 if ((!jsonInputs_.resources.customOutputImages.empty()) && (!inputResources_.customOutputImages.empty()) &&
451 (RenderHandleUtil::IsValid(inputResources_.customOutputImages[0].handle))) {
452 IRenderNodeGraphShareManager& shrMgr = renderNodeContextMgr_->GetRenderNodeGraphShareManager();
453 shrMgr.RegisterRenderNodeOutput(
454 jsonInputs_.resources.customOutputImages[0u].name, inputResources_.customOutputImages[0u].handle);
455 }
456 }
457
Execute(IRenderCommandList & cmdList)458 void RenderNodePostProcessUtil::Execute(IRenderCommandList& cmdList)
459 {
460 if (!validInputs_) {
461 return;
462 }
463
464 RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderPostProcess", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
465
466 UpdatePostProcessData(ppConfig_);
467
468 // prepare for possible layer copy if not using optimized paths for layers
469 if ((deviceBackendType_ != DeviceBackendType::VULKAN) &&
470 (images_.input.layer != PipelineStateConstants::GPU_IMAGE_ALL_LAYERS) && (!glOptimizedLayerCopyEnabled_)) {
471 BindableImage layerCopyOutput;
472 layerCopyOutput.handle = ti_.layerCopyImage.GetHandle();
473 IRenderNodeCopyUtil::CopyInfo layerCopyInfo;
474 layerCopyInfo.input = images_.input;
475 layerCopyInfo.output = layerCopyOutput;
476 layerCopyInfo.copyType = IRenderNodeCopyUtil::CopyType::LAYER_COPY;
477 renderCopyLayer_.Execute(cmdList, layerCopyInfo);
478 }
479
480 if (validInputsForTaa_ &&
481 (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_TAA_BIT)) {
482 ExecuteTAA(cmdList, { images_.input, images_.historyNext });
483 }
484
485 // NOTE: separate flare with new post process interface
486 if (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_LENS_FLARE_BIT) {
487 if (ppLensFlareInterface_.postProcessNode) {
488 auto& ppNode = *ppLensFlareInterface_.postProcessNode;
489 // inputs set in pre-execute
490 ppNode.Execute(cmdList);
491 }
492 }
493
494 // ppConfig_ is already up-to-date from PreExecuteFrame
495 if (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_BLOOM_BIT) {
496 renderBloom_.Execute(*renderNodeContextMgr_, cmdList, ppConfig_);
497 }
498
499 // post process
500 const bool fxaaEnabled =
501 ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_FXAA_BIT;
502 const bool motionBlurEnabled =
503 validInputsForMb_ &&
504 (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_MOTION_BLUR_BIT);
505 const bool dofEnabled =
506 validInputsForDof_ &&
507 (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_DOF_BIT);
508
509 // after bloom or TAA
510 const bool postProcessNeeded = (ppConfig_.enableFlags != 0);
511 const bool sameInputOutput = (images_.input.handle == images_.output.handle);
512
513 #if (RENDER_VALIDATION_ENABLED == 1)
514 if (postProcessNeeded && sameInputOutput) {
515 PLUGIN_LOG_ONCE_W(renderNodeContextMgr_->GetName().data(),
516 "%s: combined post process shader not supported for same input/output ATM.",
517 renderNodeContextMgr_->GetName().data());
518 }
519 #endif
520 uint32_t ppIdx = 0U;
521 if (postProcessNeeded && (!sameInputOutput)) {
522 ExecuteCombine(cmdList, framePostProcessInOut_[ppIdx++]);
523 }
524
525 if (fxaaEnabled) {
526 ExecuteFXAA(cmdList, framePostProcessInOut_[ppIdx++]);
527 }
528
529 if (motionBlurEnabled) {
530 const auto& inOut = framePostProcessInOut_[ppIdx++];
531 RenderMotionBlur::MotionBlurInfo info { inOut.input.handle, inOut.output.handle, images_.velocity.handle,
532 images_.depth.handle, ubos_.postProcess.GetHandle(),
533 sizeof(GlobalPostProcessStruct) + PP_MB_IDX * UBO_OFFSET_ALIGNMENT, outputSize_ };
534 renderMotionBlur_.Execute(*renderNodeContextMgr_, cmdList, info, ppConfig_);
535 }
536 if (dofEnabled) {
537 const auto& inOut = framePostProcessInOut_[ppIdx++];
538 ExecuteDof(cmdList, inOut);
539 }
540
541 // post blur
542 if (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_BLUR_BIT) {
543 ppIdx++;
544 // NOTE: add ppConfig
545 renderBlur_.Execute(*renderNodeContextMgr_, cmdList, ppConfig_);
546 }
547
548 PLUGIN_ASSERT(ppIdx == framePostProcessInOut_.size());
549
550 // if all flags are zero and output is different than input
551 // we need to execute a copy
552 if ((!postProcessNeeded) && (!sameInputOutput)) {
553 ExecuteBlit(cmdList, { images_.input, images_.output });
554 }
555 }
556
ExecuteCombine(IRenderCommandList & cmdList,const InputOutput & inOut)557 void RenderNodePostProcessUtil::ExecuteCombine(IRenderCommandList& cmdList, const InputOutput& inOut)
558 {
559 RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderCombine", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
560
561 const RenderHandle bloomImage =
562 (ppConfig_.enableFlags & PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_BLOOM_BIT)
563 ? renderBloom_.GetFinalTarget()
564 : aimg_.black;
565
566 auto& effect = glOptimizedLayerCopyEnabled_ ? combineDataLayer_ : combineData_;
567 const RenderPass renderPass = CreateRenderPass(renderNodeContextMgr_->GetGpuResourceManager(), inOut.output.handle);
568 if (!RenderHandleUtil::IsValid(effect.pso)) {
569 auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
570 const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
571 const RenderHandle graphicsStateHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(effect.sd.shader);
572 effect.pso = psoMgr.GetGraphicsPsoHandle(effect.sd.shader, graphicsStateHandle, effect.sd.pipelineLayout, {},
573 {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
574 }
575
576 cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
577 cmdList.BindPipeline(effect.pso);
578
579 {
580 RenderHandle sets[2U] {};
581 DescriptorSetLayoutBindingResources resources[2U] {};
582 {
583 const RenderHandle ubo = ubos_.postProcess.GetHandle();
584 PLUGIN_ASSERT(binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_COMBINED_IDX]);
585 auto& binder = *binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_COMBINED_IDX];
586 binder.ClearBindings();
587 uint32_t binding = 0u;
588 binder.BindBuffer(binding, ubo, 0);
589 binder.BindBuffer(++binding, ubo, sizeof(GlobalPostProcessStruct) + PP_COMBINED_IDX * UBO_OFFSET_ALIGNMENT);
590 sets[0U] = binder.GetDescriptorSetHandle();
591 resources[0U] = binder.GetDescriptorSetLayoutBindingResources();
592 }
593 {
594 auto& binder = *binders_.combineBinder;
595 binder.ClearBindings();
596 uint32_t binding = 0u;
597 BindableImage mainInput = inOut.input;
598 mainInput.samplerHandle = samplers_.linear;
599 binder.BindImage(binding++, mainInput);
600 binder.BindImage(binding++, bloomImage, samplers_.linear);
601 binder.BindImage(binding++, images_.dirtMask, samplers_.linear);
602 sets[1U] = binder.GetDescriptorSetHandle();
603 resources[1U] = binder.GetDescriptorSetLayoutBindingResources();
604 }
605 cmdList.UpdateDescriptorSets(sets, resources);
606 cmdList.BindDescriptorSets(0u, sets);
607 }
608
609 // dynamic state
610 cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(renderPass));
611 cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(renderPass));
612
613 if (effect.sd.pipelineLayoutData.pushConstant.byteSize > 0U) {
614 const float fWidth = static_cast<float>(renderPass.renderPassDesc.renderArea.extentWidth);
615 const float fHeight = static_cast<float>(renderPass.renderPassDesc.renderArea.extentHeight);
616 const float layer = glOptimizedLayerCopyEnabled_ ? float(inOut.input.layer) : 0.0f;
617 const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight },
618 { layer, 0.0f, 0.0f, 0.0f } };
619 cmdList.PushConstantData(effect.sd.pipelineLayoutData.pushConstant, arrayviewU8(pc));
620 }
621
622 cmdList.Draw(3u, 1u, 0u, 0u);
623 cmdList.EndRenderPass();
624 }
625
ExecuteFXAA(IRenderCommandList & cmdList,const InputOutput & inOut)626 void RenderNodePostProcessUtil::ExecuteFXAA(IRenderCommandList& cmdList, const InputOutput& inOut)
627 {
628 RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderFXAA", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
629
630 auto renderPass = CreateRenderPass(renderNodeContextMgr_->GetGpuResourceManager(), inOut.output.handle);
631 if (!RenderHandleUtil::IsValid(fxaaData_.pso)) {
632 auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
633 const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
634 const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(fxaaData_.sd.shader);
635 fxaaData_.pso = psoMgr.GetGraphicsPsoHandle(fxaaData_.sd.shader, gfxHandle, fxaaData_.sd.pipelineLayout, {}, {},
636 { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
637 }
638
639 cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
640 cmdList.BindPipeline(fxaaData_.pso);
641
642 {
643 RenderHandle sets[2U] {};
644 DescriptorSetLayoutBindingResources resources[2U] {};
645 {
646 const RenderHandle ubo = ubos_.postProcess.GetHandle();
647 PLUGIN_ASSERT(binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_FXAA_IDX]);
648 auto& binder = *binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_FXAA_IDX];
649 binder.ClearBindings();
650 uint32_t binding = 0u;
651 binder.BindBuffer(binding, ubo, 0u);
652 binder.BindBuffer(++binding, ubo, sizeof(GlobalPostProcessStruct) + PP_FXAA_IDX * UBO_OFFSET_ALIGNMENT);
653 sets[0U] = binder.GetDescriptorSetHandle();
654 resources[0U] = binder.GetDescriptorSetLayoutBindingResources();
655 }
656 {
657 auto& binder = *binders_.fxaaBinder;
658 binder.ClearBindings();
659 uint32_t binding = 0u;
660 binder.BindImage(binding, inOut.input);
661 binder.BindSampler(++binding, samplers_.linear);
662 sets[1U] = binder.GetDescriptorSetHandle();
663 resources[1U] = binder.GetDescriptorSetLayoutBindingResources();
664 }
665 cmdList.UpdateDescriptorSets(sets, resources);
666 cmdList.BindDescriptorSets(0u, sets);
667 }
668
669 if (fxaaData_.sd.pipelineLayoutData.pushConstant.byteSize > 0U) {
670 const LocalPostProcessPushConstantStruct pc { ti_.targetSize,
671 PostProcessConversionHelper::GetFactorFxaa(ppConfig_) };
672 cmdList.PushConstantData(fxaaData_.sd.pipelineLayoutData.pushConstant, arrayviewU8(pc));
673 }
674
675 // dynamic state
676 cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(renderPass));
677 cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(renderPass));
678
679 cmdList.Draw(3u, 1u, 0u, 0u);
680 cmdList.EndRenderPass();
681 }
682
ExecuteTAA(IRenderCommandList & cmdList,const InputOutput & inOut)683 void RenderNodePostProcessUtil::ExecuteTAA(IRenderCommandList& cmdList, const InputOutput& inOut)
684 {
685 RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderTAA", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
686
687 auto renderPass = CreateRenderPass(renderNodeContextMgr_->GetGpuResourceManager(), inOut.output.handle);
688 if (!RenderHandleUtil::IsValid(taaData_.pso)) {
689 const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
690 auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
691 const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(taaData_.sd.shader);
692 taaData_.pso = psoMgr.GetGraphicsPsoHandle(taaData_.sd.shader, gfxHandle, taaData_.sd.pipelineLayout, {}, {},
693 { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
694 }
695
696 cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
697 cmdList.BindPipeline(taaData_.pso);
698
699 {
700 RenderHandle sets[2U] {};
701 DescriptorSetLayoutBindingResources resources[2U] {};
702 {
703 const RenderHandle ubo = ubos_.postProcess.GetHandle();
704 PLUGIN_ASSERT(binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_TAA_IDX]);
705 auto& binder = *binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_TAA_IDX];
706 binder.ClearBindings();
707 uint32_t binding = 0u;
708 binder.BindBuffer(binding++, ubo, 0u);
709 binder.BindBuffer(binding++, ubo, sizeof(GlobalPostProcessStruct) + PP_TAA_IDX * UBO_OFFSET_ALIGNMENT);
710 sets[0U] = binder.GetDescriptorSetHandle();
711 resources[0U] = binder.GetDescriptorSetLayoutBindingResources();
712 }
713 {
714 auto& binder = *binders_.taaBinder;
715 binder.ClearBindings();
716 uint32_t binding = 0u;
717 binder.BindImage(binding, images_.depth.handle);
718 binder.BindImage(++binding, inOut.input.handle);
719 binder.BindImage(++binding, images_.velocity.handle);
720 binder.BindImage(++binding, images_.history.handle);
721 binder.BindSampler(++binding, samplers_.linear);
722 sets[1U] = binder.GetDescriptorSetHandle();
723 resources[1U] = binder.GetDescriptorSetLayoutBindingResources();
724 }
725 cmdList.UpdateDescriptorSets(sets, resources);
726 cmdList.BindDescriptorSets(0U, sets);
727 }
728
729 if (taaData_.sd.pipelineLayoutData.pushConstant.byteSize > 0U) {
730 const float fWidth = static_cast<float>(renderPass.renderPassDesc.renderArea.extentWidth);
731 const float fHeight = static_cast<float>(renderPass.renderPassDesc.renderArea.extentHeight);
732 const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight },
733 PostProcessConversionHelper::GetFactorTaa(ppConfig_) };
734 cmdList.PushConstantData(taaData_.sd.pipelineLayoutData.pushConstant, arrayviewU8(pc));
735 }
736
737 // dynamic state
738 cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(renderPass));
739 cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(renderPass));
740
741 cmdList.Draw(3u, 1u, 0u, 0u);
742 cmdList.EndRenderPass();
743 }
744
ExecuteDofBlur(IRenderCommandList & cmdList,const InputOutput & inOut)745 void RenderNodePostProcessUtil::ExecuteDofBlur(IRenderCommandList& cmdList, const InputOutput& inOut)
746 {
747 RenderPass rp;
748 {
749 const GpuImageDesc desc =
750 renderNodeContextMgr_->GetGpuResourceManager().GetImageDescriptor(ti_.mipImages[0U].GetHandle());
751 rp.renderPassDesc.attachmentCount = 2u;
752 rp.renderPassDesc.attachmentHandles[0u] = ti_.mipImages[0U].GetHandle();
753 rp.renderPassDesc.attachments[0u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
754 rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
755 rp.renderPassDesc.attachmentHandles[1u] = ti_.mipImages[1U].GetHandle();
756 rp.renderPassDesc.attachments[1u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
757 rp.renderPassDesc.attachments[1u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
758 rp.renderPassDesc.renderArea = { 0, 0, desc.width, desc.height };
759
760 rp.renderPassDesc.subpassCount = 1u;
761 rp.subpassDesc.colorAttachmentCount = 2u;
762 rp.subpassDesc.colorAttachmentIndices[0u] = 0u;
763 rp.subpassDesc.colorAttachmentIndices[1u] = 1u;
764 rp.subpassStartIndex = 0u;
765 }
766 if (!RenderHandleUtil::IsValid(dofBlurData_.pso)) {
767 auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
768 const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
769 const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(dofBlurData_.sd.shader);
770 dofBlurData_.pso = psoMgr.GetGraphicsPsoHandle(dofBlurData_.sd.shader, gfxHandle,
771 dofBlurData_.sd.pipelineLayout, {}, {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
772 }
773 cmdList.BeginRenderPass(rp.renderPassDesc, rp.subpassStartIndex, rp.subpassDesc);
774 cmdList.BindPipeline(dofBlurData_.pso);
775
776 {
777 RenderHandle sets[2U] {};
778 DescriptorSetLayoutBindingResources resources[2U] {};
779 {
780 // NOTE: this updated descriptor set is used in dof
781 const RenderHandle ubo = ubos_.postProcess.GetHandle();
782 PLUGIN_ASSERT(binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_DOF_IDX]);
783 auto& binder = *binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_DOF_IDX];
784 binder.ClearBindings();
785 uint32_t binding = 0u;
786 binder.BindBuffer(binding, ubo, 0u);
787 binder.BindBuffer(++binding, ubo, sizeof(GlobalPostProcessStruct) + PP_DOF_IDX * UBO_OFFSET_ALIGNMENT);
788 sets[0U] = binder.GetDescriptorSetHandle();
789 resources[0U] = binder.GetDescriptorSetLayoutBindingResources();
790 }
791 {
792 auto& binder = *binders_.dofBlurBinder;
793 binder.ClearBindings();
794 uint32_t binding = 0u;
795 BindableImage input = inOut.input;
796 input.samplerHandle = samplers_.mipLinear;
797 binder.BindImage(binding, input);
798 BindableImage depth = images_.depth;
799 depth.samplerHandle = samplers_.nearest;
800 binder.BindImage(++binding, depth);
801 sets[1U] = binder.GetDescriptorSetHandle();
802 resources[1U] = binder.GetDescriptorSetLayoutBindingResources();
803 }
804 cmdList.UpdateDescriptorSets(sets, resources);
805 cmdList.BindDescriptorSets(0U, sets);
806 }
807
808 {
809 const float fWidth = static_cast<float>(rp.renderPassDesc.renderArea.extentWidth);
810 const float fHeight = static_cast<float>(rp.renderPassDesc.renderArea.extentHeight);
811 const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight }, {} };
812 cmdList.PushConstantData(dofBlurData_.sd.pipelineLayoutData.pushConstant, arrayviewU8(pc));
813 }
814
815 // dynamic state
816 cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(rp));
817 cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(rp));
818
819 cmdList.Draw(3u, 1u, 0u, 0u);
820 cmdList.EndRenderPass();
821 const auto maxMipLevel = ppConfig_.blurConfiguration.maxMipLevel;
822 ppConfig_.blurConfiguration.maxMipLevel = static_cast<uint32_t>(Math::round(ppConfig_.dofConfiguration.nearBlur));
823 renderNearBlur_.Execute(*renderNodeContextMgr_, cmdList, ppConfig_);
824 ppConfig_.blurConfiguration.maxMipLevel = static_cast<uint32_t>(Math::round(ppConfig_.dofConfiguration.farBlur));
825 renderFarBlur_.Execute(*renderNodeContextMgr_, cmdList, ppConfig_);
826 ppConfig_.blurConfiguration.maxMipLevel = maxMipLevel;
827 }
828
ExecuteDof(IRenderCommandList & cmdList,const InputOutput & inOut)829 void RenderNodePostProcessUtil::ExecuteDof(IRenderCommandList& cmdList, const InputOutput& inOut)
830 {
831 RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderDoF", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
832
833 // NOTE: updates set 0 for dof
834 ExecuteDofBlur(cmdList, inOut);
835
836 auto renderPass = CreateRenderPass(renderNodeContextMgr_->GetGpuResourceManager(), inOut.output.handle);
837 if (!RenderHandleUtil::IsValid(dofData_.pso)) {
838 auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
839 const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
840 const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(dofData_.sd.shader);
841 dofData_.pso = psoMgr.GetGraphicsPsoHandle(dofData_.sd.shader, gfxHandle, dofData_.sd.pipelineLayout, {}, {},
842 { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
843 }
844
845 cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
846 cmdList.BindPipeline(dofData_.pso);
847
848 RenderHandle sets[2u] {};
849 {
850 // NOTE: descriptor set updated by DOF blur
851 PLUGIN_ASSERT(binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_DOF_IDX]);
852 auto& binder = *binders_.globalSet0[POST_PROCESS_UBO_INDICES::PP_DOF_IDX];
853 sets[0u] = binder.GetDescriptorSetHandle();
854 }
855 {
856 auto& binder = *binders_.dofBinder;
857 binder.ClearBindings();
858 uint32_t binding = 0u;
859 BindableImage input = inOut.input;
860 input.samplerHandle = samplers_.mipLinear;
861 binder.BindImage(binding, input);
862 binder.BindImage(++binding, ti_.mipImages[0U].GetHandle(), samplers_.mipLinear);
863 binder.BindImage(++binding, ti_.mipImages[1U].GetHandle(), samplers_.mipLinear);
864 BindableImage depth = images_.depth;
865 depth.samplerHandle = samplers_.nearest;
866 binder.BindImage(++binding, depth);
867
868 cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources());
869 sets[1u] = binder.GetDescriptorSetHandle();
870 }
871 cmdList.BindDescriptorSets(0u, sets);
872
873 if (dofData_.sd.pipelineLayoutData.pushConstant.byteSize > 0U) {
874 const float fWidth = static_cast<float>(renderPass.renderPassDesc.renderArea.extentWidth);
875 const float fHeight = static_cast<float>(renderPass.renderPassDesc.renderArea.extentHeight);
876 const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight }, {} };
877 cmdList.PushConstantData(dofData_.sd.pipelineLayoutData.pushConstant, arrayviewU8(pc));
878 }
879
880 // dynamic state
881 cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(renderPass));
882 cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(renderPass));
883
884 cmdList.Draw(3u, 1u, 0u, 0u);
885 cmdList.EndRenderPass();
886 }
887
ExecuteBlit(IRenderCommandList & cmdList,const InputOutput & inOut)888 void RenderNodePostProcessUtil::ExecuteBlit(IRenderCommandList& cmdList, const InputOutput& inOut)
889 {
890 // extra blit from input to ouput
891 if (RenderHandleUtil::IsGpuImage(inOut.input.handle) && RenderHandleUtil::IsGpuImage(inOut.output.handle)) {
892 #if (RENDER_VALIDATION_ENABLED == 1)
893 PLUGIN_LOG_ONCE_W(renderNodeContextMgr_->GetName().data(),
894 "RENDER_PERFORMANCE_VALIDATION: Extra blit from input to output (RN: %s)",
895 renderNodeContextMgr_->GetName().data());
896 #endif
897 RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderBlit", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
898
899 auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
900
901 RenderPass renderPass = CreateRenderPass(gpuResourceMgr, inOut.output.handle);
902 auto& effect = copyData_;
903 if (!RenderHandleUtil::IsValid(effect.pso)) {
904 auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
905 const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
906 const RenderHandle graphicsStateHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(effect.sd.shader);
907 effect.pso = psoMgr.GetGraphicsPsoHandle(effect.sd.shader, graphicsStateHandle, effect.sd.pipelineLayout,
908 {}, {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
909 }
910
911 cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
912 cmdList.BindPipeline(effect.pso);
913
914 {
915 auto& binder = *binders_.copyBinder;
916 binder.ClearBindings();
917 uint32_t binding = 0u;
918 binder.BindSampler(binding, samplers_.linear);
919 binder.BindImage(++binding, inOut.input);
920 cmdList.UpdateDescriptorSet(
921 binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources());
922 cmdList.BindDescriptorSet(0u, binder.GetDescriptorSetHandle());
923 }
924
925 // dynamic state
926 const ViewportDesc viewportDesc = renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(renderPass);
927 const ScissorDesc scissorDesc = renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(renderPass);
928 cmdList.SetDynamicStateViewport(viewportDesc);
929 cmdList.SetDynamicStateScissor(scissorDesc);
930
931 cmdList.Draw(3u, 1u, 0u, 0u);
932 cmdList.EndRenderPass();
933 }
934 }
935
UpdatePostProcessData(const PostProcessConfiguration & postProcessConfiguration)936 void RenderNodePostProcessUtil::UpdatePostProcessData(const PostProcessConfiguration& postProcessConfiguration)
937 {
938 auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
939 const RenderPostProcessConfiguration rppc =
940 renderNodeContextMgr_->GetRenderNodeUtil().GetRenderPostProcessConfiguration(postProcessConfiguration);
941 PLUGIN_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == sizeof(RenderPostProcessConfiguration));
942 if (auto* const data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(ubos_.postProcess.GetHandle())); data) {
943 const auto* dataEnd = data + POST_PROCESS_UBO_BYTE_SIZE;
944 if (!CloneData(data, size_t(dataEnd - data), &rppc, sizeof(RenderPostProcessConfiguration))) {
945 PLUGIN_LOG_E("post process ubo copying failed.");
946 }
947 {
948 auto* localData = data + (sizeof(RenderPostProcessConfiguration) + PP_TAA_IDX * UBO_OFFSET_ALIGNMENT);
949 auto factor = PostProcessConversionHelper::GetFactorTaa(postProcessConfiguration);
950 CloneData(localData, size_t(dataEnd - localData), &factor, sizeof(factor));
951 }
952 {
953 auto* localData = data + (sizeof(RenderPostProcessConfiguration) + PP_BLOOM_IDX * UBO_OFFSET_ALIGNMENT);
954 auto factor = PostProcessConversionHelper::GetFactorBloom(postProcessConfiguration);
955 CloneData(localData, size_t(dataEnd - localData), &factor, sizeof(factor));
956 }
957 {
958 auto* localData = data + (sizeof(RenderPostProcessConfiguration) + PP_BLUR_IDX * UBO_OFFSET_ALIGNMENT);
959 auto factor = PostProcessConversionHelper::GetFactorBlur(postProcessConfiguration);
960 CloneData(localData, size_t(dataEnd - localData), &factor, sizeof(factor));
961 }
962 {
963 auto* localData = data + (sizeof(RenderPostProcessConfiguration) + PP_FXAA_IDX * UBO_OFFSET_ALIGNMENT);
964 auto factor = PostProcessConversionHelper::GetFactorFxaa(postProcessConfiguration);
965 CloneData(localData, size_t(dataEnd - localData), &factor, sizeof(factor));
966 }
967 {
968 auto* localData = data + (sizeof(RenderPostProcessConfiguration) + PP_DOF_IDX * UBO_OFFSET_ALIGNMENT);
969 auto factors = PostProcessConversionHelper::GetFactorDof(postProcessConfiguration);
970 CloneData(localData, size_t(dataEnd - localData), &factors, sizeof(factors));
971 localData += sizeof(factors);
972 factors = PostProcessConversionHelper::GetFactorDof2(postProcessConfiguration);
973 CloneData(localData, size_t(dataEnd - localData), &factors, sizeof(factors));
974 }
975 {
976 auto* localData = data + (sizeof(RenderPostProcessConfiguration) + PP_MB_IDX * UBO_OFFSET_ALIGNMENT);
977 auto factor = PostProcessConversionHelper::GetFactorMotionBlur(postProcessConfiguration);
978 CloneData(localData, size_t(dataEnd - localData), &factor, sizeof(factor));
979 }
980
981 gpuResourceMgr.UnmapBuffer(ubos_.postProcess.GetHandle());
982 }
983 }
984
ProcessPostProcessConfiguration()985 void RenderNodePostProcessUtil::ProcessPostProcessConfiguration()
986 {
987 if (!jsonInputs_.renderDataStore.dataStoreName.empty()) {
988 auto& dsMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
989 if (const IRenderDataStore* ds = dsMgr.GetRenderDataStore(jsonInputs_.renderDataStore.dataStoreName); ds) {
990 if (jsonInputs_.renderDataStore.typeName == RenderDataStorePod::TYPE_NAME) {
991 auto const dataStore = static_cast<const IRenderDataStorePod*>(ds);
992 auto const dataView = dataStore->Get(jsonInputs_.renderDataStore.configurationName);
993 if (dataView.data() && (dataView.size_bytes() == sizeof(PostProcessConfiguration))) {
994 ppConfig_ = *((const PostProcessConfiguration*)dataView.data());
995 if (RenderHandleUtil::IsValid(ppConfig_.bloomConfiguration.dirtMaskImage)) {
996 images_.dirtMask = ppConfig_.bloomConfiguration.dirtMaskImage;
997 } else {
998 images_.dirtMask = aimg_.black;
999 }
1000 }
1001 }
1002 }
1003 }
1004 }
1005
InitCreateShaderResources()1006 void RenderNodePostProcessUtil::InitCreateShaderResources()
1007 {
1008 const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
1009
1010 combineData_ = {};
1011 combineDataLayer_ = {};
1012 copyData_ = {};
1013 fxaaData_ = {};
1014 taaData_ = {};
1015 dofData_ = {};
1016 dofBlurData_ = {};
1017
1018 combineData_.sd = shaderMgr.GetShaderDataByShaderName(COMBINED_SHADER_NAME);
1019 combineDataLayer_.sd = shaderMgr.GetShaderDataByShaderName(COMBINED_LAYER_SHADER_NAME);
1020 copyData_.sd = shaderMgr.GetShaderDataByShaderName(COPY_SHADER_NAME);
1021 fxaaData_.sd = shaderMgr.GetShaderDataByShaderName(FXAA_SHADER_NAME);
1022 taaData_.sd = shaderMgr.GetShaderDataByShaderName(TAA_SHADER_NAME);
1023 dofData_.sd = shaderMgr.GetShaderDataByShaderName(DOF_SHADER_NAME);
1024 dofBlurData_.sd = shaderMgr.GetShaderDataByShaderName(DOF_BLUR_SHADER_NAME);
1025 }
1026
InitCreateBinders()1027 void RenderNodePostProcessUtil::InitCreateBinders()
1028 {
1029 INodeContextDescriptorSetManager& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
1030 {
1031 constexpr uint32_t globalSetIdx = 0u;
1032 constexpr uint32_t localSetIdx = 1u;
1033
1034 for (uint32_t idx = 0; idx < POST_PROCESS_UBO_INDICES::PP_COUNT_IDX; ++idx) {
1035 binders_.globalSet0[idx] = descriptorSetMgr.CreateDescriptorSetBinder(
1036 descriptorSetMgr.CreateDescriptorSet(globalSetIdx, combineData_.sd.pipelineLayoutData),
1037 combineData_.sd.pipelineLayoutData.descriptorSetLayouts[globalSetIdx].bindings);
1038 }
1039
1040 binders_.combineBinder = descriptorSetMgr.CreateDescriptorSetBinder(
1041 descriptorSetMgr.CreateDescriptorSet(localSetIdx, combineData_.sd.pipelineLayoutData),
1042 combineData_.sd.pipelineLayoutData.descriptorSetLayouts[localSetIdx].bindings);
1043 binders_.combineLayerBinder = descriptorSetMgr.CreateDescriptorSetBinder(
1044 descriptorSetMgr.CreateDescriptorSet(localSetIdx, combineDataLayer_.sd.pipelineLayoutData),
1045 combineDataLayer_.sd.pipelineLayoutData.descriptorSetLayouts[localSetIdx].bindings);
1046
1047 binders_.fxaaBinder = descriptorSetMgr.CreateDescriptorSetBinder(
1048 descriptorSetMgr.CreateDescriptorSet(localSetIdx, fxaaData_.sd.pipelineLayoutData),
1049 fxaaData_.sd.pipelineLayoutData.descriptorSetLayouts[localSetIdx].bindings);
1050 binders_.taaBinder = descriptorSetMgr.CreateDescriptorSetBinder(
1051 descriptorSetMgr.CreateDescriptorSet(localSetIdx, taaData_.sd.pipelineLayoutData),
1052 taaData_.sd.pipelineLayoutData.descriptorSetLayouts[localSetIdx].bindings);
1053
1054 binders_.dofBlurBinder = descriptorSetMgr.CreateDescriptorSetBinder(
1055 descriptorSetMgr.CreateDescriptorSet(localSetIdx, dofBlurData_.sd.pipelineLayoutData),
1056 dofBlurData_.sd.pipelineLayoutData.descriptorSetLayouts[localSetIdx].bindings);
1057 binders_.dofBinder = descriptorSetMgr.CreateDescriptorSetBinder(
1058 descriptorSetMgr.CreateDescriptorSet(localSetIdx, dofData_.sd.pipelineLayoutData),
1059 dofData_.sd.pipelineLayoutData.descriptorSetLayouts[localSetIdx].bindings);
1060 }
1061 binders_.copyBinder = descriptorSetMgr.CreateDescriptorSetBinder(
1062 descriptorSetMgr.CreateDescriptorSet(0u, copyData_.sd.pipelineLayoutData),
1063 copyData_.sd.pipelineLayoutData.descriptorSetLayouts[0u].bindings);
1064 }
1065
ParseRenderNodeInputs()1066 void RenderNodePostProcessUtil::ParseRenderNodeInputs()
1067 {
1068 const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil();
1069 const auto jsonVal = renderNodeContextMgr_->GetNodeJson();
1070 jsonInputs_.resources = parserUtil.GetInputResources(jsonVal, "resources");
1071 jsonInputs_.renderDataStore = parserUtil.GetRenderDataStore(jsonVal, "renderDataStore");
1072
1073 const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
1074 inputResources_ = renderNodeUtil.CreateInputResources(jsonInputs_.resources);
1075 jsonInputs_.hasChangeableResourceHandles = renderNodeUtil.HasChangeableResources(jsonInputs_.resources);
1076
1077 // process custom inputs
1078 for (uint32_t idx = 0; idx < static_cast<uint32_t>(jsonInputs_.resources.customInputImages.size()); ++idx) {
1079 const auto& ref = jsonInputs_.resources.customInputImages[idx];
1080 if (ref.usageName == INPUT_COLOR) {
1081 jsonInputs_.colorIndex = idx;
1082 } else if (ref.usageName == INPUT_DEPTH) {
1083 jsonInputs_.depthIndex = idx;
1084 } else if (ref.usageName == INPUT_VELOCITY) {
1085 jsonInputs_.velocityIndex = idx;
1086 } else if (ref.usageName == INPUT_HISTORY) {
1087 jsonInputs_.historyIndex = idx;
1088 } else if (ref.usageName == INPUT_HISTORY_NEXT) {
1089 jsonInputs_.historyNextIndex = idx;
1090 }
1091 }
1092 }
1093
UpdateImageData()1094 void RenderNodePostProcessUtil::UpdateImageData()
1095 {
1096 if ((!RenderHandleUtil::IsValid(aimg_.black)) || (!RenderHandleUtil::IsValid(aimg_.white))) {
1097 auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1098 aimg_.black = gpuResourceMgr.GetImageHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_GPU_IMAGE);
1099 aimg_.white = gpuResourceMgr.GetImageHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_GPU_IMAGE_WHITE);
1100 }
1101
1102 if (postProcessInfo_.parseRenderNodeInputs) {
1103 if (inputResources_.customInputImages.empty() || inputResources_.customOutputImages.empty()) {
1104 return; // early out
1105 }
1106
1107 images_.input.handle = inputResources_.customInputImages[0].handle;
1108 images_.output.handle = inputResources_.customOutputImages[0].handle;
1109 if (jsonInputs_.depthIndex < inputResources_.customInputImages.size()) {
1110 images_.depth.handle = inputResources_.customInputImages[jsonInputs_.depthIndex].handle;
1111 }
1112 if (jsonInputs_.velocityIndex < inputResources_.customInputImages.size()) {
1113 images_.velocity.handle = inputResources_.customInputImages[jsonInputs_.velocityIndex].handle;
1114 }
1115 if (jsonInputs_.historyIndex < inputResources_.customInputImages.size()) {
1116 images_.history.handle = inputResources_.customInputImages[jsonInputs_.historyIndex].handle;
1117 }
1118 if (jsonInputs_.historyNextIndex < inputResources_.customInputImages.size()) {
1119 images_.historyNext.handle = inputResources_.customInputImages[jsonInputs_.historyNextIndex].handle;
1120 }
1121 } else {
1122 images_.input = postProcessInfo_.imageData.input;
1123 images_.output = postProcessInfo_.imageData.output;
1124 images_.depth = postProcessInfo_.imageData.depth;
1125 images_.velocity = postProcessInfo_.imageData.velocity;
1126 images_.history = postProcessInfo_.imageData.history;
1127 images_.historyNext = postProcessInfo_.imageData.historyNext;
1128 }
1129
1130 validInputsForTaa_ = false;
1131 validInputsForDof_ = false;
1132 validInputsForMb_ = false;
1133 bool validDepth = false;
1134 bool validHistory = false;
1135 bool validVelocity = false;
1136 if (IsValidHandle(images_.depth) && (images_.depth.handle != aimg_.white)) {
1137 const IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1138 const GpuImageDesc& desc = gpuResourceMgr.GetImageDescriptor(images_.depth.handle);
1139 if (desc.usageFlags & CORE_IMAGE_USAGE_SAMPLED_BIT) {
1140 validDepth = true;
1141 }
1142 } else {
1143 images_.depth.handle = aimg_.white; // default depth
1144 }
1145 if (IsValidHandle(images_.velocity) && (images_.velocity.handle != aimg_.black)) {
1146 const IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1147 const GpuImageDesc& desc = gpuResourceMgr.GetImageDescriptor(images_.velocity.handle);
1148 if (desc.usageFlags & CORE_IMAGE_USAGE_SAMPLED_BIT) {
1149 validVelocity = true;
1150 }
1151 } else {
1152 images_.velocity.handle = aimg_.black; // default velocity
1153 }
1154 if (IsValidHandle(images_.history) && IsValidHandle(images_.historyNext)) {
1155 const IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1156 const GpuImageDesc& velDesc = gpuResourceMgr.GetImageDescriptor(images_.velocity.handle);
1157 if (velDesc.usageFlags & CORE_IMAGE_USAGE_SAMPLED_BIT) {
1158 validHistory = true;
1159 }
1160 }
1161 if (!RenderHandleUtil::IsValid(images_.dirtMask)) {
1162 images_.dirtMask = aimg_.black; // default dirt mask
1163 }
1164
1165 validInputsForDof_ = validDepth;
1166 validInputsForTaa_ = validDepth && validHistory; // TAA can be used without velocities
1167 validInputsForMb_ = validVelocity;
1168 }
1169
CreatePostProcessInterfaces()1170 void RenderNodePostProcessUtil::CreatePostProcessInterfaces()
1171 {
1172 auto* renderClassFactory = renderNodeContextMgr_->GetRenderContext().GetInterface<IClassFactory>();
1173 if (renderClassFactory) {
1174 ppLensFlareInterface_.postProcess =
1175 CreateInstance<IRenderPostProcess>(*renderClassFactory, RenderPostProcessFlare::UID);
1176 if (ppLensFlareInterface_.postProcess) {
1177 ppLensFlareInterface_.postProcessNode = CreateInstance<IRenderPostProcessNode>(
1178 *renderClassFactory, ppLensFlareInterface_.postProcess->GetRenderPostProcessNodeUid());
1179 }
1180 }
1181 }
1182
1183 ///////////////////////////////////////////////////////////////////////////////////////////////////
1184
Init(IRenderNodeContextManager & renderNodeContextMgr,const IRenderNodePostProcessUtil::PostProcessInfo & postProcessInfo)1185 void RenderNodePostProcessUtilImpl::Init(
1186 IRenderNodeContextManager& renderNodeContextMgr, const IRenderNodePostProcessUtil::PostProcessInfo& postProcessInfo)
1187 {
1188 rn_.Init(renderNodeContextMgr, postProcessInfo);
1189 }
1190
PreExecute(const IRenderNodePostProcessUtil::PostProcessInfo & postProcessInfo)1191 void RenderNodePostProcessUtilImpl::PreExecute(const IRenderNodePostProcessUtil::PostProcessInfo& postProcessInfo)
1192 {
1193 rn_.PreExecute(postProcessInfo);
1194 }
1195
Execute(IRenderCommandList & cmdList)1196 void RenderNodePostProcessUtilImpl::Execute(IRenderCommandList& cmdList)
1197 {
1198 rn_.Execute(cmdList);
1199 }
1200
GetInterface(const Uid & uid) const1201 const IInterface* RenderNodePostProcessUtilImpl::GetInterface(const Uid& uid) const
1202 {
1203 if ((uid == IRenderNodePostProcessUtil::UID) || (uid == IInterface::UID)) {
1204 return this;
1205 }
1206 return nullptr;
1207 }
1208
GetInterface(const Uid & uid)1209 IInterface* RenderNodePostProcessUtilImpl::GetInterface(const Uid& uid)
1210 {
1211 if ((uid == IRenderNodePostProcessUtil::UID) || (uid == IInterface::UID)) {
1212 return this;
1213 }
1214 return nullptr;
1215 }
1216
Ref()1217 void RenderNodePostProcessUtilImpl::Ref()
1218 {
1219 refCount_++;
1220 }
1221
Unref()1222 void RenderNodePostProcessUtilImpl::Unref()
1223 {
1224 if (--refCount_ == 0) {
1225 delete this;
1226 }
1227 }
1228 RENDER_END_NAMESPACE()
1229