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