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_default_env.h"
17 
18 #include <algorithm>
19 
20 #include <3d/render/default_material_constants.h>
21 #include <3d/render/intf_render_data_store_default_camera.h>
22 #include <3d/render/intf_render_data_store_default_light.h>
23 #include <3d/render/intf_render_data_store_default_scene.h>
24 #include <3d/render/render_data_defines_3d.h>
25 #include <base/containers/string.h>
26 #include <base/math/matrix.h>
27 #include <base/math/matrix_util.h>
28 #include <core/log.h>
29 #include <core/namespace.h>
30 #include <render/datastore/intf_render_data_store.h>
31 #include <render/datastore/intf_render_data_store_manager.h>
32 #include <render/datastore/intf_render_data_store_pod.h>
33 #include <render/datastore/render_data_store_render_pods.h>
34 #include <render/device/intf_gpu_resource_manager.h>
35 #include <render/device/intf_shader_manager.h>
36 #include <render/nodecontext/intf_node_context_descriptor_set_manager.h>
37 #include <render/nodecontext/intf_node_context_pso_manager.h>
38 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
39 #include <render/nodecontext/intf_render_command_list.h>
40 #include <render/nodecontext/intf_render_node_context_manager.h>
41 #include <render/nodecontext/intf_render_node_parser_util.h>
42 #include <render/nodecontext/intf_render_node_util.h>
43 
44 #include "render/render_node_scene_util.h"
45 
46 namespace {
47 #include <3d/shaders/common/3d_dm_structures_common.h>
48 #include <render/shaders/common/render_post_process_structs_common.h>
49 } // namespace
50 CORE3D_BEGIN_NAMESPACE()
51 using namespace BASE_NS;
52 using namespace RENDER_NS;
53 
54 namespace {
55 constexpr string_view MULTIVIEW_VARIANT_NAME { "ENV_MV" };
56 
57 constexpr string_view POST_PROCESS_DATA_STORE_TYPE_NAME { "RenderDataStorePod" };
58 constexpr DynamicStateEnum DYNAMIC_STATES[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR };
59 constexpr DynamicStateEnum DYNAMIC_STATES_FSR[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR,
60     CORE_DYNAMIC_STATE_ENUM_FRAGMENT_SHADING_RATE };
61 
62 // our light weight straight to screen post processes are only interested in these
63 static constexpr uint32_t POST_PROCESS_IMPORTANT_FLAGS_MASK { 0xffu };
64 
65 static constexpr uint32_t CUSTOM_SET_DESCRIPTOR_SET_COUNT { 3u };
66 static constexpr uint32_t FIXED_CUSTOM_SET2 { 2u };
67 
68 struct InputEnvironmentDataHandles {
69     RenderHandle cubeHandle;
70     RenderHandle texHandle;
71     float lodLevel { 0.0f };
72 };
73 
GetEnvironmentDataHandles(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderNodeDefaultEnv::DefaultImages & defaultImages,const RenderCamera::Environment & renderEnvironment)74 InputEnvironmentDataHandles GetEnvironmentDataHandles(IRenderNodeGpuResourceManager& gpuResourceMgr,
75     const RenderNodeDefaultEnv::DefaultImages& defaultImages, const RenderCamera::Environment& renderEnvironment)
76 {
77     InputEnvironmentDataHandles iedh;
78     iedh.texHandle = defaultImages.texHandle;
79     iedh.cubeHandle = defaultImages.cubeHandle;
80 
81     if (renderEnvironment.envMap) {
82         const RenderHandle handle = renderEnvironment.envMap.GetHandle();
83         const GpuImageDesc desc = gpuResourceMgr.GetImageDescriptor(handle);
84         if ((renderEnvironment.backgroundType == RenderCamera::Environment::BG_TYPE_IMAGE) ||
85             (renderEnvironment.backgroundType == RenderCamera::Environment::BG_TYPE_EQUIRECTANGULAR)) {
86             if (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D) {
87                 iedh.texHandle = handle;
88             } else {
89                 CORE_LOG_E("invalid environment map, type does not match background type");
90             }
91         } else if (renderEnvironment.backgroundType == RenderCamera::Environment::BG_TYPE_CUBEMAP) {
92             if (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_CUBE) {
93                 iedh.cubeHandle = handle;
94             } else {
95                 CORE_LOG_E("invalid environment map, type does not match background type");
96             }
97         }
98         iedh.lodLevel = renderEnvironment.envMapLodLevel;
99     }
100     return iedh;
101 }
102 } // namespace
103 
InitNode(IRenderNodeContextManager & renderNodeContextMgr)104 void RenderNodeDefaultEnv::InitNode(IRenderNodeContextManager& renderNodeContextMgr)
105 {
106     renderNodeContextMgr_ = &renderNodeContextMgr;
107     ParseRenderNodeInputs();
108 
109     const auto& renderNodeGraphData = renderNodeContextMgr_->GetRenderNodeGraphData();
110     stores_ = RenderNodeSceneUtil::GetSceneRenderDataStores(
111         renderNodeContextMgr, renderNodeGraphData.renderNodeGraphDataStoreName);
112 
113     currentScene_ = {};
114     currentBgType_ = { RenderCamera::Environment::BG_TYPE_NONE };
115 
116     if ((jsonInputs_.nodeFlags & RenderSceneFlagBits::RENDER_SCENE_DIRECT_POST_PROCESS_BIT) &&
117         jsonInputs_.renderDataStore.dataStoreName.empty()) {
118         CORE_LOG_V("%s: render data store post process configuration not set in render node graph",
119             renderNodeContextMgr_->GetName().data());
120     }
121 
122     auto& gpuResourceMgr = renderNodeContextMgr.GetGpuResourceManager();
123     cubemapSampler =
124         gpuResourceMgr.GetSamplerHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_RADIANCE_CUBEMAP_SAMPLER);
125     defaultImages_.texHandle =
126         gpuResourceMgr.GetImageHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_MATERIAL_BASE_COLOR);
127     defaultImages_.cubeHandle =
128         gpuResourceMgr.GetImageHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_SKYBOX_CUBEMAP);
129     rngRenderPass_ = renderNodeContextMgr.GetRenderNodeUtil().CreateRenderPass(inputRenderPass_);
130     GetSceneUniformBuffers(stores_.dataStoreNameScene);
131 
132     const auto& shaderMgr = renderNodeContextMgr.GetShaderManager();
133     // default pipeline layout
134     {
135         const RenderHandle plHandle =
136             shaderMgr.GetPipelineLayoutHandle(DefaultMaterialShaderConstants::PIPELINE_LAYOUT_ENV);
137         defaultPipelineLayout_ = shaderMgr.GetPipelineLayout(plHandle);
138     }
139     shaderHandle_ = shaderMgr.GetShaderHandle(DefaultMaterialShaderConstants::ENV_SHADER_NAME);
140 
141     CreateDescriptorSets();
142 }
143 
PreExecuteFrame()144 void RenderNodeDefaultEnv::PreExecuteFrame()
145 {
146     // re-create needed gpu resources
147 }
148 
ExecuteFrame(IRenderCommandList & cmdList)149 void RenderNodeDefaultEnv::ExecuteFrame(IRenderCommandList& cmdList)
150 {
151     const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
152     const auto* dataStoreScene =
153         static_cast<IRenderDataStoreDefaultScene*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
154     const auto* dataStoreCamera =
155         static_cast<IRenderDataStoreDefaultCamera*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
156     const auto* dataStoreLight =
157         static_cast<IRenderDataStoreDefaultLight*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameLight));
158 
159     if (dataStoreLight && dataStoreCamera && dataStoreScene) {
160         UpdateCurrentScene(*dataStoreScene, *dataStoreCamera);
161     }
162 
163     cmdList.BeginRenderPass(renderPass_.renderPassDesc, renderPass_.subpassStartIndex, renderPass_.subpassDesc);
164 
165     if (currentScene_.camera.environment.backgroundType != RenderCamera::Environment::BG_TYPE_NONE) {
166         if (currentScene_.camera.layerMask & currentScene_.camera.environment.layerMask) {
167             UpdatePostProcessConfiguration();
168             RenderData(cmdList);
169         }
170     }
171 
172     cmdList.EndRenderPass();
173 }
174 
RenderData(IRenderCommandList & cmdList)175 void RenderNodeDefaultEnv::RenderData(IRenderCommandList& cmdList)
176 {
177     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
178 
179     cmdList.SetDynamicStateViewport(currentScene_.viewportDesc);
180     cmdList.SetDynamicStateScissor(currentScene_.scissorDesc);
181     if (fsrEnabled_) {
182         cmdList.SetDynamicStateFragmentShadingRate(
183             { 1u, 1u }, FragmentShadingRateCombinerOps { CORE_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE,
184                             CORE_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE });
185     }
186 
187     const RenderCamera::Environment& renderEnv = currentScene_.camera.environment;
188     const RenderHandle shaderHandle = renderEnv.shader ? renderEnv.shader.GetHandle() : shaderHandle_;
189     // check for pso changes
190     if ((renderEnv.backgroundType != currentBgType_) || (shaderHandle.id != shaderHandle_.id) ||
191         (currentCameraShaderFlags_ != currentScene_.cameraShaderFlags) || (!RenderHandleUtil::IsValid(psoHandle_))) {
192         currentBgType_ = currentScene_.camera.environment.backgroundType;
193         currentCameraShaderFlags_ = currentScene_.cameraShaderFlags;
194         psoHandle_ = GetPso(shaderHandle, currentBgType_, currentRenderPPConfiguration_);
195     }
196 
197     cmdList.BindPipeline(psoHandle_);
198 
199     {
200         // set 0, ubos
201         auto& binder0 = *allDescriptorSets_.set0;
202         {
203             uint32_t bindingIndex = 0;
204             binder0.BindBuffer(bindingIndex++, sceneBuffers_.camera, 0u);
205             binder0.BindBuffer(bindingIndex++, cameraBuffers_.generalData, 0u);
206             binder0.BindBuffer(bindingIndex++, cameraBuffers_.environment, 0u);
207             binder0.BindBuffer(bindingIndex++, cameraBuffers_.fog, 0u);
208             binder0.BindBuffer(bindingIndex++, cameraBuffers_.postProcess, 0u);
209         }
210 
211         const auto envDataHandles =
212             GetEnvironmentDataHandles(gpuResourceMgr, defaultImages_, currentScene_.camera.environment);
213         // set 1, bind combined image samplers
214         auto& binder1 = *allDescriptorSets_.set1;
215         {
216             uint32_t bindingIndex = 0;
217             binder1.BindImage(bindingIndex++, envDataHandles.texHandle, cubemapSampler);
218             binder1.BindImage(bindingIndex++, envDataHandles.cubeHandle, cubemapSampler);
219         }
220 
221         const RenderHandle handles[] { binder0.GetDescriptorSetHandle(), binder1.GetDescriptorSetHandle() };
222         const DescriptorSetLayoutBindingResources resources[] { binder0.GetDescriptorSetLayoutBindingResources(),
223             binder1.GetDescriptorSetLayoutBindingResources() };
224         cmdList.UpdateDescriptorSets(handles, resources);
225     }
226 
227     // bind build-in sets
228     const RenderHandle descSets[] = { allDescriptorSets_.set0->GetDescriptorSetHandle(),
229         allDescriptorSets_.set1->GetDescriptorSetHandle() };
230     cmdList.BindDescriptorSets(0u, descSets);
231 
232     // custom set 2 resources
233     bool validDraw = true;
234     if (customSet2_) {
235         validDraw = (renderEnv.customResourceHandles[0]) ? true : false;
236         validDraw = validDraw && UpdateAndBindCustomSet(cmdList, renderEnv);
237     }
238 
239     if (validDraw) {
240         cmdList.Draw(3u, 1u, 0u, 0u);
241     }
242 }
243 
UpdateAndBindCustomSet(IRenderCommandList & cmdList,const RenderCamera::Environment & renderEnv)244 bool RenderNodeDefaultEnv::UpdateAndBindCustomSet(
245     IRenderCommandList& cmdList, const RenderCamera::Environment& renderEnv)
246 {
247     IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
248     INodeContextDescriptorSetManager& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
249     const IRenderNodeShaderManager& shaderMgr = renderNodeContextMgr_->GetShaderManager();
250 
251     RenderHandle currPlHandle = shaderMgr.GetPipelineLayoutHandleByShaderHandle(renderEnv.shader.GetHandle());
252     if (!RenderHandleUtil::IsValid(currPlHandle)) {
253         currPlHandle = shaderMgr.GetReflectionPipelineLayoutHandle(renderEnv.shader.GetHandle());
254     }
255     const PipelineLayout& plRef = shaderMgr.GetPipelineLayout(currPlHandle);
256     const auto& descBindings = plRef.descriptorSetLayouts[FIXED_CUSTOM_SET2].bindings;
257     const RenderHandle descSetHandle = descriptorSetMgr.CreateOneFrameDescriptorSet(descBindings);
258     bool valid = false;
259     uint32_t validResCount = 0;
260     for (uint32_t idx = 0; idx < RenderSceneDataConstants::MAX_ENV_CUSTOM_RESOURCE_COUNT; ++idx) {
261         if (renderEnv.customResourceHandles[idx]) {
262             validResCount++;
263         } else {
264             break;
265         }
266     }
267     const array_view<const RenderHandleReference> customResourceHandles(renderEnv.customResourceHandles, validResCount);
268     if (RenderHandleUtil::IsValid(descSetHandle) && (descBindings.size() == customResourceHandles.size())) {
269         IDescriptorSetBinder::Ptr binderPtr = descriptorSetMgr.CreateDescriptorSetBinder(descSetHandle, descBindings);
270         if (binderPtr) {
271             auto& binder = *binderPtr;
272             for (uint32_t idx = 0; idx < static_cast<uint32_t>(customResourceHandles.size()); ++idx) {
273                 CORE_ASSERT(idx < descBindings.size());
274                 const RenderHandle currRes = customResourceHandles[idx].GetHandle();
275                 if (gpuResourceMgr.IsGpuBuffer(currRes)) {
276                     binder.BindBuffer(idx, currRes, 0);
277                 } else if (gpuResourceMgr.IsGpuImage(currRes)) {
278                     if (descBindings[idx].descriptorType ==
279                         DescriptorType::CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
280                         binder.BindImage(idx, currRes, cubemapSampler);
281                     } else {
282                         binder.BindImage(idx, currRes);
283                     }
284                 } else if (gpuResourceMgr.IsGpuSampler(currRes)) {
285                     binder.BindSampler(idx, currRes);
286                 }
287             }
288 
289             // user generated setup, we check for validity of all bindings in the descriptor set
290             if (binder.GetDescriptorSetLayoutBindingValidity()) {
291                 cmdList.UpdateDescriptorSet(
292                     binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources());
293                 cmdList.BindDescriptorSet(FIXED_CUSTOM_SET2, binder.GetDescriptorSetHandle());
294                 valid = true;
295             }
296         }
297     }
298     if (!valid) {
299 #if (CORE3D_VALIDATION_ENABLED == 1)
300         CORE_LOG_ONCE_W("default_env_custom_res_issue",
301             "invalid bindings with custom shader descriptor set 2 (render node: %s)",
302             renderNodeContextMgr_->GetName().data());
303 #endif
304     }
305     return valid;
306 }
307 
UpdateCurrentScene(const IRenderDataStoreDefaultScene & dataStoreScene,const IRenderDataStoreDefaultCamera & dataStoreCamera)308 void RenderNodeDefaultEnv::UpdateCurrentScene(
309     const IRenderDataStoreDefaultScene& dataStoreScene, const IRenderDataStoreDefaultCamera& dataStoreCamera)
310 {
311     if (jsonInputs_.hasChangeableRenderPassHandles) {
312         const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
313         inputRenderPass_ = renderNodeUtil.CreateInputRenderPass(jsonInputs_.renderPass);
314         rngRenderPass_ = renderNodeContextMgr_->GetRenderNodeUtil().CreateRenderPass(inputRenderPass_);
315     }
316     // get default RNG based render pass setup
317     renderPass_ = rngRenderPass_;
318 
319     const auto scene = dataStoreScene.GetScene();
320     bool hasCustomCamera = false;
321     bool isNamedCamera = false; // NOTE: legacy support will be removed
322     uint32_t cameraIdx = scene.cameraIndex;
323     if (jsonInputs_.customCameraId != INVALID_CAM_ID) {
324         cameraIdx = dataStoreCamera.GetCameraIndex(jsonInputs_.customCameraId);
325         hasCustomCamera = true;
326     } else if (!(jsonInputs_.customCameraName.empty())) {
327         cameraIdx = dataStoreCamera.GetCameraIndex(jsonInputs_.customCameraName);
328         hasCustomCamera = true;
329         isNamedCamera = true;
330     }
331 
332     if (const auto cameras = dataStoreCamera.GetCameras(); cameraIdx < (uint32_t)cameras.size()) {
333         // store current frame camera
334         currentScene_.camera = cameras[cameraIdx];
335     }
336 
337     // renderpass needs to be valid (created in init)
338     if (hasCustomCamera) {
339         // uses camera based clear-setup
340         RenderNodeSceneUtil::UpdateRenderPassFromCustomCamera(currentScene_.camera, isNamedCamera, renderPass_);
341     } else {
342         RenderNodeSceneUtil::UpdateRenderPassFromCamera(currentScene_.camera, renderPass_);
343     }
344     currentScene_.viewportDesc = RenderNodeSceneUtil::CreateViewportFromCamera(currentScene_.camera);
345     currentScene_.scissorDesc = RenderNodeSceneUtil::CreateScissorFromCamera(currentScene_.camera);
346     currentScene_.viewportDesc.minDepth = 1.0f;
347     currentScene_.viewportDesc.maxDepth = 1.0f;
348 
349     currentScene_.cameraShaderFlags = currentScene_.camera.shaderFlags;
350     // remove fog explicitly if render node graph input and/or default render slot usage states so
351     if (jsonInputs_.nodeFlags & RenderSceneFlagBits::RENDER_SCENE_DISABLE_FOG_BIT) {
352         currentScene_.cameraShaderFlags &= (~RenderCamera::ShaderFlagBits::CAMERA_SHADER_FOG_BIT);
353     }
354     // add multi-view flags if needed
355     ResetRenderSlotData(renderPass_.subpassDesc.viewMask > 1U);
356 }
357 
GetPso(const RenderHandle shaderHandle,const RenderCamera::Environment::BackgroundType bgType,const RenderPostProcessConfiguration & renderPostProcessConfiguration)358 RenderHandle RenderNodeDefaultEnv::GetPso(const RenderHandle shaderHandle,
359     const RenderCamera::Environment::BackgroundType bgType,
360     const RenderPostProcessConfiguration& renderPostProcessConfiguration)
361 {
362     if (RenderHandleUtil::GetHandleType(shaderHandle) == RenderHandleType::SHADER_STATE_OBJECT) {
363         const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
364         const ShaderSpecializationConstantView sscv = shaderMgr.GetReflectionSpecialization(shaderHandle);
365         vector<uint32_t> flags(sscv.constants.size());
366 
367         constexpr uint32_t defaultEnvType = 0u;
368         constexpr uint32_t postProcessFlags = 3u;
369         constexpr uint32_t cameraFlags = 4u;
370 
371         for (const auto& ref : sscv.constants) {
372             const uint32_t constantId = ref.offset / sizeof(uint32_t);
373 
374             if (ref.shaderStage == ShaderStageFlagBits::CORE_SHADER_STAGE_FRAGMENT_BIT) {
375                 switch (ref.id) {
376                     case defaultEnvType:
377                         flags[constantId] = (uint32_t)bgType;
378                         break;
379                     case postProcessFlags:
380                         flags[constantId] = renderPostProcessConfiguration.flags.x;
381                         break;
382                     case cameraFlags:
383                         flags[constantId] = currentScene_.cameraShaderFlags;
384                         break;
385                     default:
386                         break;
387                 }
388             }
389         }
390 
391         const ShaderSpecializationConstantDataView specialization { sscv.constants, flags };
392         RenderHandle plHandle = shaderMgr.GetPipelineLayoutHandleByShaderHandle(shaderHandle);
393         if (!RenderHandleUtil::IsValid(plHandle)) {
394             plHandle = shaderMgr.GetReflectionPipelineLayoutHandle(shaderHandle);
395         }
396         const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(shaderHandle);
397         // flag that we need additional custom resource bindings
398         customSet2_ = shaderMgr.GetPipelineLayout(plHandle).descriptorSetCount == CUSTOM_SET_DESCRIPTOR_SET_COUNT;
399         psoHandle_ = renderNodeContextMgr_->GetPsoManager().GetGraphicsPsoHandle(
400             shaderHandle, gfxHandle, plHandle, {}, specialization, GetDynamicStates());
401     }
402     return psoHandle_;
403 }
404 
CreateDescriptorSets()405 void RenderNodeDefaultEnv::CreateDescriptorSets()
406 {
407     auto& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
408     {
409         // automatic calculation
410         const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
411         const DescriptorCounts dc = renderNodeUtil.GetDescriptorCounts(defaultPipelineLayout_);
412         descriptorSetMgr.ResetAndReserve(dc);
413     }
414 
415     CORE_ASSERT(defaultPipelineLayout_.descriptorSetCount == 2u);
416     {
417         const uint32_t set = 0u;
418         const RenderHandle descriptorSetHandle = descriptorSetMgr.CreateDescriptorSet(set, defaultPipelineLayout_);
419         allDescriptorSets_.set0 = descriptorSetMgr.CreateDescriptorSetBinder(
420             descriptorSetHandle, defaultPipelineLayout_.descriptorSetLayouts[set].bindings);
421     }
422     {
423         const uint32_t set = 1u;
424         const RenderHandle descriptorSetHandle = descriptorSetMgr.CreateDescriptorSet(set, defaultPipelineLayout_);
425         allDescriptorSets_.set1 = descriptorSetMgr.CreateDescriptorSetBinder(
426             descriptorSetHandle, defaultPipelineLayout_.descriptorSetLayouts[set].bindings);
427     }
428 }
429 
UpdatePostProcessConfiguration()430 void RenderNodeDefaultEnv::UpdatePostProcessConfiguration()
431 {
432     if (jsonInputs_.nodeFlags & RenderSceneFlagBits::RENDER_SCENE_DIRECT_POST_PROCESS_BIT) {
433         if (!jsonInputs_.renderDataStore.dataStoreName.empty()) {
434             auto const& dsMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
435             if (const IRenderDataStore* ds = dsMgr.GetRenderDataStore(jsonInputs_.renderDataStore.dataStoreName); ds) {
436                 if (jsonInputs_.renderDataStore.typeName == POST_PROCESS_DATA_STORE_TYPE_NAME) {
437                     auto const dataStore = static_cast<IRenderDataStorePod const*>(ds);
438                     auto const dataView = dataStore->Get(jsonInputs_.renderDataStore.configurationName);
439                     if (dataView.data() && (dataView.size_bytes() == sizeof(PostProcessConfiguration))) {
440                         const PostProcessConfiguration* data = (const PostProcessConfiguration*)dataView.data();
441                         currentRenderPPConfiguration_ =
442                             renderNodeContextMgr_->GetRenderNodeUtil().GetRenderPostProcessConfiguration(*data);
443                         currentRenderPPConfiguration_.flags.x =
444                             (currentRenderPPConfiguration_.flags.x & POST_PROCESS_IMPORTANT_FLAGS_MASK);
445                     }
446                 }
447             }
448         }
449     }
450 }
451 
GetSceneUniformBuffers(const string_view us)452 void RenderNodeDefaultEnv::GetSceneUniformBuffers(const string_view us)
453 {
454     sceneBuffers_ = RenderNodeSceneUtil::GetSceneBufferHandles(*renderNodeContextMgr_, stores_.dataStoreNameScene);
455 
456     string camName;
457     if (jsonInputs_.customCameraId != INVALID_CAM_ID) {
458         camName = to_string(jsonInputs_.customCameraId);
459     } else if (!(jsonInputs_.customCameraName.empty())) {
460         camName = jsonInputs_.customCameraName;
461     }
462     cameraBuffers_ =
463         RenderNodeSceneUtil::GetSceneCameraBufferHandles(*renderNodeContextMgr_, stores_.dataStoreNameScene, camName);
464 }
465 
GetDynamicStates() const466 array_view<const DynamicStateEnum> RenderNodeDefaultEnv::GetDynamicStates() const
467 {
468     if (fsrEnabled_) {
469         return { DYNAMIC_STATES_FSR, countof(DYNAMIC_STATES_FSR) };
470     } else {
471         return { DYNAMIC_STATES, countof(DYNAMIC_STATES) };
472     }
473 }
474 
ParseRenderNodeInputs()475 void RenderNodeDefaultEnv::ParseRenderNodeInputs()
476 {
477     const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil();
478     const auto jsonVal = renderNodeContextMgr_->GetNodeJson();
479     jsonInputs_.renderPass = parserUtil.GetInputRenderPass(jsonVal, "renderPass");
480     jsonInputs_.customCameraName = parserUtil.GetStringValue(jsonVal, "customCameraName");
481     jsonInputs_.customCameraId = parserUtil.GetUintValue(jsonVal, "customCameraId");
482     jsonInputs_.renderDataStore = parserUtil.GetRenderDataStore(jsonVal, "renderDataStore");
483 
484     jsonInputs_.nodeFlags = static_cast<uint32_t>(parserUtil.GetUintValue(jsonVal, "nodeFlags"));
485     if (jsonInputs_.nodeFlags == ~0u) {
486         jsonInputs_.nodeFlags = 0;
487     }
488 
489     EvaluateFogBits();
490 
491     const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
492     inputRenderPass_ = renderNodeUtil.CreateInputRenderPass(jsonInputs_.renderPass);
493     if ((inputRenderPass_.fragmentShadingRateAttachmentIndex < inputRenderPass_.attachments.size()) &&
494         RenderHandleUtil::IsValid(
495             inputRenderPass_.attachments[inputRenderPass_.fragmentShadingRateAttachmentIndex].handle)) {
496         fsrEnabled_ = true;
497     }
498     jsonInputs_.hasChangeableRenderPassHandles = renderNodeUtil.HasChangeableResources(jsonInputs_.renderPass);
499 }
500 
ResetRenderSlotData(const bool enableMultiview)501 void RenderNodeDefaultEnv::ResetRenderSlotData(const bool enableMultiview)
502 {
503     // can be reset to multi-view usage or reset back to default usage
504     if (enableMultiView_ != enableMultiview) {
505         enableMultiView_ = enableMultiview;
506         const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
507         shaderHandle_ = enableMultiView_ ? shaderMgr.GetShaderHandle(
508                                                DefaultMaterialShaderConstants::ENV_SHADER_NAME, MULTIVIEW_VARIANT_NAME)
509                                          : shaderMgr.GetShaderHandle(DefaultMaterialShaderConstants::ENV_SHADER_NAME);
510         psoHandle_ = {};
511     }
512 }
513 
EvaluateFogBits()514 void RenderNodeDefaultEnv::EvaluateFogBits()
515 {
516     // if no explicit bits set we check default render slot usages
517     if ((jsonInputs_.nodeFlags & (RENDER_SCENE_ENABLE_FOG_BIT | RENDER_SCENE_DISABLE_FOG_BIT)) == 0) {
518         jsonInputs_.nodeFlags |= RenderSceneFlagBits::RENDER_SCENE_ENABLE_FOG_BIT;
519     }
520 }
521 
522 // for plugin / factory interface
Create()523 RENDER_NS::IRenderNode* RenderNodeDefaultEnv::Create()
524 {
525     return new RenderNodeDefaultEnv();
526 }
527 
Destroy(IRenderNode * instance)528 void RenderNodeDefaultEnv::Destroy(IRenderNode* instance)
529 {
530     delete static_cast<RenderNodeDefaultEnv*>(instance);
531 }
532 CORE3D_END_NAMESPACE()
533