• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "render_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 POST_PROCESS_DATA_STORE_TYPE_NAME { "RenderDataStorePod" };
57 constexpr DynamicStateEnum DYNAMIC_STATES[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR };
58 constexpr DynamicStateEnum DYNAMIC_STATES_FSR[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR,
59     CORE_DYNAMIC_STATE_ENUM_FRAGMENT_SHADING_RATE };
60 
61 constexpr string_view DEFAULT_SKY_SHADER_NAME { "3dshaders://shader/clouds/core3d_dm_env_sky.shader" };
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 static constexpr uint32_t FIXED_CUSTOM_SET3 { 3U };
65 static constexpr uint32_t FIXED_CUSTOM_SET1 { 1U };
66 
67 struct FrameGlobalDescriptorSets {
68     RenderHandle set0;
69     bool valid = false;
70 };
71 
GetFrameGlobalDescriptorSets(IRenderNodeContextManager * rncm,const SceneRenderDataStores & stores,const string & cameraName)72 FrameGlobalDescriptorSets GetFrameGlobalDescriptorSets(
73     IRenderNodeContextManager* rncm, const SceneRenderDataStores& stores, const string& cameraName)
74 {
75     FrameGlobalDescriptorSets fgds;
76     if (rncm) {
77         // re-fetch global descriptor sets every frame
78         const INodeContextDescriptorSetManager& dsMgr = rncm->GetDescriptorSetManager();
79         const string_view us = stores.dataStoreNameScene;
80         fgds.set0 = dsMgr.GetGlobalDescriptorSet(
81             us + DefaultMaterialMaterialConstants::MATERIAL_SET0_GLOBAL_DESCRIPTOR_SET_PREFIX_NAME + cameraName);
82         fgds.valid = RenderHandleUtil::IsValid(fgds.set0);
83         if (!fgds.valid) {
84             CORE_LOG_ONCE_E("core3d_global_descriptor_set_env_all_issues",
85                 "Global descriptor set 0 for default material not "
86                 "found (RenderNodeDefaultCameraController needed)");
87         }
88     }
89     return fgds;
90 }
91 
92 struct InputEnvironmentDataHandles {
93     RenderHandle cubeHandle;
94     RenderHandle cubeBlenderHandle;
95     RenderHandle texHandle;
96     float lodLevel { 0.0f };
97 };
98 
GetEnvironmentDataHandles(const IRenderDataStoreDefaultCamera & dsCamera,IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderNodeDefaultEnv::DefaultImages & defaultImages,const RenderCamera & cam)99 InputEnvironmentDataHandles GetEnvironmentDataHandles(const IRenderDataStoreDefaultCamera& dsCamera,
100     IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderNodeDefaultEnv::DefaultImages& defaultImages,
101     const RenderCamera& cam)
102 {
103     InputEnvironmentDataHandles iedh;
104     iedh.texHandle = defaultImages.texHandle;
105     iedh.cubeHandle = defaultImages.cubeHandle;
106     iedh.cubeBlenderHandle = defaultImages.cubeHandle;
107 
108     const auto& env = cam.environment;
109     const bool dynCubemap = (env.multiEnvCount > 0U);
110     if (env.envMap || dynCubemap) {
111         const RenderHandle handle = env.envMap.GetHandle();
112         const GpuImageDesc desc = gpuResourceMgr.GetImageDescriptor(handle);
113         if ((env.backgroundType == RenderCamera::Environment::BG_TYPE_IMAGE) ||
114             (env.backgroundType == RenderCamera::Environment::BG_TYPE_EQUIRECTANGULAR)) {
115             if (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D) {
116                 iedh.texHandle = handle;
117             } else {
118                 CORE_LOG_ONCE_E("inv_env_2d_bg_type", "invalid environment map, type does not match background type");
119             }
120         } else if (env.backgroundType == RenderCamera::Environment::BG_TYPE_CUBEMAP) {
121             bool valid = false;
122             if (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_CUBE) {
123                 iedh.cubeHandle = handle;
124                 valid = true;
125             }
126             if (dynCubemap && (env.multiEnvCount >= 2U)) {
127                 CORE_STATIC_ASSERT(DefaultMaterialCameraConstants::MAX_CAMERA_MULTI_ENVIRONMENT_COUNT >= 2U);
128                 const RenderCamera::Environment env1 = dsCamera.GetEnvironment(env.multiEnvIds[0U]);
129                 const RenderCamera::Environment env2 = dsCamera.GetEnvironment(env.multiEnvIds[1U]);
130                 iedh.cubeHandle = env1.envMap.GetHandle();
131                 iedh.cubeBlenderHandle = env2.envMap.GetHandle();
132                 valid = true;
133             }
134             if (!valid) {
135                 CORE_LOG_ONCE_E("inv_env_cu_bg_type", "invalid environment map, type does not match background type");
136             }
137         }
138         iedh.lodLevel = env.envMapLodLevel;
139     }
140     return iedh;
141 }
142 } // namespace
143 
InitNode(IRenderNodeContextManager & renderNodeContextMgr)144 void RenderNodeDefaultEnv::InitNode(IRenderNodeContextManager& renderNodeContextMgr)
145 {
146     renderNodeContextMgr_ = &renderNodeContextMgr;
147     ParseRenderNodeInputs();
148 
149     const auto& renderNodeGraphData = renderNodeContextMgr_->GetRenderNodeGraphData();
150     stores_ = RenderNodeSceneUtil::GetSceneRenderDataStores(
151         renderNodeContextMgr, renderNodeGraphData.renderNodeGraphDataStoreName);
152 
153     currentScene_ = {};
154     currentBgType_ = { RenderCamera::Environment::BG_TYPE_NONE };
155 
156     if ((jsonInputs_.nodeFlags & RenderSceneFlagBits::RENDER_SCENE_DIRECT_POST_PROCESS_BIT) &&
157         jsonInputs_.renderDataStore.dataStoreName.empty()) {
158         CORE_LOG_V("%s: render data store post process configuration not set in render node graph",
159             renderNodeContextMgr_->GetName().data());
160     }
161 
162     auto& gpuResourceMgr = renderNodeContextMgr.GetGpuResourceManager();
163     cubemapSampler =
164         gpuResourceMgr.GetSamplerHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_RADIANCE_CUBEMAP_SAMPLER);
165     defaultImages_.texHandle =
166         gpuResourceMgr.GetImageHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_MATERIAL_BASE_COLOR);
167     defaultImages_.cubeHandle =
168         gpuResourceMgr.GetImageHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_SKYBOX_CUBEMAP);
169     rngRenderPass_ = renderNodeContextMgr.GetRenderNodeUtil().CreateRenderPass(inputRenderPass_);
170 
171     const auto& shaderMgr = renderNodeContextMgr.GetShaderManager();
172 
173     const IShaderManager::RenderSlotData shaderRsd = shaderMgr.GetRenderSlotData(jsonInputs_.renderSlotId);
174     defaultShaderData_.shader = shaderRsd.shader.GetHandle();
175     defaultShaderData_.pl = shaderRsd.pipelineLayout.GetHandle();
176     defaultShaderData_.plData = shaderMgr.GetPipelineLayout(defaultShaderData_.pl);
177     defaultSkyShader_ = shaderMgr.GetShaderHandle(DEFAULT_SKY_SHADER_NAME);
178 
179     CreateDescriptorSets();
180 }
181 
PreExecuteFrame()182 void RenderNodeDefaultEnv::PreExecuteFrame()
183 {
184     // re-create needed gpu resources
185 }
186 
ExecuteFrame(IRenderCommandList & cmdList)187 void RenderNodeDefaultEnv::ExecuteFrame(IRenderCommandList& cmdList)
188 {
189     const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
190     const auto* dataStoreScene =
191         static_cast<IRenderDataStoreDefaultScene*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
192     const auto* dataStoreCamera =
193         static_cast<IRenderDataStoreDefaultCamera*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
194     const auto* dataStoreLight =
195         static_cast<IRenderDataStoreDefaultLight*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameLight));
196 
197     if (dataStoreLight && dataStoreCamera && dataStoreScene) {
198         UpdateCurrentScene(*dataStoreScene, *dataStoreCamera);
199     }
200 
201     RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "3DEnv", DefaultDebugConstants::DEFAULT_DEBUG_COLOR);
202 
203     cmdList.BeginRenderPass(renderPass_.renderPassDesc, renderPass_.subpassStartIndex, renderPass_.subpassDesc);
204 
205     if (dataStoreCamera && currentScene_.camera.environment.backgroundType != RenderCamera::Environment::BG_TYPE_NONE) {
206         if (currentScene_.camera.layerMask & currentScene_.camera.environment.layerMask) {
207             UpdatePostProcessConfiguration();
208             RenderData(*dataStoreCamera, cmdList);
209         }
210     }
211 
212     cmdList.EndRenderPass();
213 }
214 
RenderData(const IRenderDataStoreDefaultCamera & dsCamera,IRenderCommandList & cmdList)215 void RenderNodeDefaultEnv::RenderData(const IRenderDataStoreDefaultCamera& dsCamera, IRenderCommandList& cmdList)
216 {
217     // re-fetch global descriptor sets every frame
218     FrameGlobalDescriptorSets fgds = GetFrameGlobalDescriptorSets(renderNodeContextMgr_, stores_, cameraName_);
219     if (!fgds.valid) {
220         return;
221     }
222 
223     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
224 
225     cmdList.SetDynamicStateViewport(currentScene_.viewportDesc);
226     cmdList.SetDynamicStateScissor(currentScene_.scissorDesc);
227     if (fsrEnabled_) {
228         cmdList.SetDynamicStateFragmentShadingRate(
229             { 1u, 1u }, FragmentShadingRateCombinerOps { CORE_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE,
230                             CORE_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE });
231     }
232 
233     const RenderCamera::Environment& renderEnv = currentScene_.camera.environment;
234     // sky or basic default
235     const RenderHandle defaultShader = (renderEnv.backgroundType == RenderCamera::Environment::BG_TYPE_SKY)
236                                            ? defaultSkyShader_
237                                            : defaultShaderData_.shader;
238     const RenderHandle shaderHandle = renderEnv.shader ? renderEnv.shader.GetHandle() : defaultShader;
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     // NOTE: we only update the set3 so we can use reflection for that
289     if (!RenderHandleUtil::IsValid(currPlHandle)) {
290         currPlHandle = shaderMgr.GetReflectionPipelineLayoutHandle(renderEnv.shader.GetHandle());
291     }
292     if (!RenderHandleUtil::IsValid(currPlHandle)) {
293         currPlHandle = defaultShaderData_.pl;
294     }
295 
296     uint32_t validResCount = 0;
297     for (uint32_t idx = 0; idx < RenderSceneDataConstants::MAX_ENV_CUSTOM_RESOURCE_COUNT; ++idx) {
298         if (renderEnv.customResourceHandles[idx]) {
299             validResCount++;
300         } else {
301             break;
302         }
303     }
304     const array_view<const RenderHandleReference> customResourceHandles(renderEnv.customResourceHandles, validResCount);
305     const PipelineLayout& plRef = shaderMgr.GetPipelineLayout(currPlHandle);
306     const auto& descBindings = plRef.descriptorSetLayouts[currShaderData_.customSetIndex].bindings;
307     const RenderHandle descSetHandle = descriptorSetMgr.CreateOneFrameDescriptorSet(descBindings);
308     if (!RenderHandleUtil::IsValid(descSetHandle) || (descBindings.size() != customResourceHandles.size())) {
309         return false;
310     }
311     IDescriptorSetBinder::Ptr binderPtr = descriptorSetMgr.CreateDescriptorSetBinder(descSetHandle, descBindings);
312     if (!binderPtr) {
313         return false;
314     }
315     bool valid = false;
316 
317     auto& binder = *binderPtr;
318     for (uint32_t idx = 0; idx < static_cast<uint32_t>(customResourceHandles.size()); ++idx) {
319         CORE_ASSERT(idx < descBindings.size());
320         const RenderHandle currRes = customResourceHandles[idx].GetHandle();
321         if (gpuResourceMgr.IsGpuBuffer(currRes)) {
322             binder.BindBuffer(idx, currRes, 0);
323         } else if (gpuResourceMgr.IsGpuImage(currRes)) {
324             if (descBindings[idx].descriptorType == DescriptorType::CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
325                 binder.BindImage(idx, currRes, cubemapSampler);
326             } else {
327                 binder.BindImage(idx, currRes);
328             }
329         } else if (gpuResourceMgr.IsGpuSampler(currRes)) {
330             binder.BindSampler(idx, currRes);
331         }
332     }
333 
334     // user generated setup, we check for validity of all bindings in the descriptor set
335     if (binder.GetDescriptorSetLayoutBindingValidity()) {
336         cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources());
337         cmdList.BindDescriptorSet(currShaderData_.customSetIndex, binder.GetDescriptorSetHandle());
338         valid = true;
339     }
340 
341     if (!valid) {
342 #if (CORE3D_VALIDATION_ENABLED == 1)
343         CORE_LOG_ONCE_W("default_env_custom_res_issue",
344             "invalid bindings with custom shader descriptor set 1 or 3 (render node: %s)",
345             renderNodeContextMgr_->GetName().data());
346 #endif
347     }
348     return valid;
349 }
350 
UpdateCurrentScene(const IRenderDataStoreDefaultScene & dataStoreScene,const IRenderDataStoreDefaultCamera & dataStoreCamera)351 void RenderNodeDefaultEnv::UpdateCurrentScene(
352     const IRenderDataStoreDefaultScene& dataStoreScene, const IRenderDataStoreDefaultCamera& dataStoreCamera)
353 {
354     if (jsonInputs_.hasChangeableRenderPassHandles) {
355         const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
356         inputRenderPass_ = renderNodeUtil.CreateInputRenderPass(jsonInputs_.renderPass);
357         rngRenderPass_ = renderNodeContextMgr_->GetRenderNodeUtil().CreateRenderPass(inputRenderPass_);
358     }
359     // get default RNG based render pass setup
360     renderPass_ = rngRenderPass_;
361 
362     const auto scene = dataStoreScene.GetScene();
363     bool hasCustomCamera = false;
364     bool isNamedCamera = false; // NOTE: legacy support will be removed
365     uint32_t cameraIdx = scene.cameraIndex;
366     if (jsonInputs_.customCameraId != INVALID_CAM_ID) {
367         cameraIdx = dataStoreCamera.GetCameraIndex(jsonInputs_.customCameraId);
368         hasCustomCamera = true;
369     } else if (!(jsonInputs_.customCameraName.empty())) {
370         cameraIdx = dataStoreCamera.GetCameraIndex(jsonInputs_.customCameraName);
371         hasCustomCamera = true;
372         isNamedCamera = true;
373     }
374 
375     if (const auto cameras = dataStoreCamera.GetCameras(); cameraIdx < (uint32_t)cameras.size()) {
376         // store current frame camera
377         currentScene_.camera = cameras[cameraIdx];
378     }
379 
380     // renderpass needs to be valid (created in init)
381     if (hasCustomCamera) {
382         // uses camera based clear-setup
383         RenderNodeSceneUtil::UpdateRenderPassFromCustomCamera(currentScene_.camera, isNamedCamera, renderPass_);
384     } else {
385         RenderNodeSceneUtil::UpdateRenderPassFromCamera(currentScene_.camera, renderPass_);
386     }
387     currentScene_.viewportDesc = RenderNodeSceneUtil::CreateViewportFromCamera(currentScene_.camera);
388     currentScene_.scissorDesc = RenderNodeSceneUtil::CreateScissorFromCamera(currentScene_.camera);
389     currentScene_.viewportDesc.minDepth = 1.0f;
390     currentScene_.viewportDesc.maxDepth = 1.0f;
391 
392     currentScene_.cameraShaderFlags = currentScene_.camera.shaderFlags;
393     // remove fog explicitly if render node graph input and/or default render slot usage states so
394     if (jsonInputs_.nodeFlags & RenderSceneFlagBits::RENDER_SCENE_DISABLE_FOG_BIT) {
395         currentScene_.cameraShaderFlags &= (~RenderCamera::ShaderFlagBits::CAMERA_SHADER_FOG_BIT);
396     }
397     // add multi-view flags if needed
398     ResetRenderSlotData(renderPass_.subpassDesc.viewMask > 1U);
399 }
400 
GetPso(const RenderHandle shaderHandle,const RenderCamera::Environment::BackgroundType bgType,const RenderPostProcessConfiguration & renderPostProcessConfiguration)401 RenderNodeDefaultEnv::ShaderData RenderNodeDefaultEnv::GetPso(const RenderHandle shaderHandle,
402     const RenderCamera::Environment::BackgroundType bgType,
403     const RenderPostProcessConfiguration& renderPostProcessConfiguration)
404 {
405     ShaderData sd;
406     if (RenderHandleUtil::GetHandleType(shaderHandle) == RenderHandleType::SHADER_STATE_OBJECT) {
407         const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
408         const ShaderSpecializationConstantView sscv = shaderMgr.GetReflectionSpecialization(shaderHandle);
409         vector<uint32_t> flags(sscv.constants.size());
410         for (const auto& ref : sscv.constants) {
411             const uint32_t constantId = ref.offset / sizeof(uint32_t);
412             if (ref.shaderStage == ShaderStageFlagBits::CORE_SHADER_STAGE_FRAGMENT_BIT) {
413                 if (ref.id == CORE_DM_CONSTANT_ID_MATERIAL_TYPE) {
414                     flags[constantId] = 0U;
415                 } else if (ref.id == CORE_DM_CONSTANT_ID_MATERIAL_FLAGS) {
416                     flags[constantId] = 0U;
417                 } else if (ref.id == CORE_DM_CONSTANT_ID_LIGHTING_FLAGS) {
418                     flags[constantId] = 0U;
419                 } else if (ref.id == CORE_DM_CONSTANT_ID_POST_PROCESS_FLAGS) {
420                     flags[constantId] = currentRenderPPConfiguration_.flags.x;
421                 } else if (ref.id == CORE_DM_CONSTANT_ID_CAMERA_FLAGS) {
422                     flags[constantId] = currentCameraShaderFlags_;
423                 } else if (ref.id == CORE_DM_CONSTANT_ID_ENV_TYPE) {
424                     flags[constantId] = (uint32_t)bgType;
425                 }
426             }
427         }
428 
429         const ShaderSpecializationConstantDataView specialization { sscv.constants, flags };
430         // NOTE: we cannot use the reflected pipeline layout as it needs to match the real pipeline layout
431         // need to use the default as the set 0 is default material pipeline set
432         RenderHandle plHandle = defaultShaderData_.pl;
433 
434         const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(shaderHandle);
435         // flag that we need additional custom resource bindings
436         if (!((shaderHandle == defaultShaderData_.shader) || (shaderHandle == defaultSkyShader_))) {
437             plHandle = shaderMgr.GetPipelineLayoutHandleByShaderHandle(shaderHandle);
438             if (!RenderHandleUtil::IsValid(plHandle)) {
439                 plHandle = shaderMgr.GetReflectionPipelineLayoutHandle(shaderHandle);
440             }
441             const auto& plData = shaderMgr.GetPipelineLayout(plHandle);
442             if (!plData.descriptorSetLayouts[FIXED_CUSTOM_SET3].bindings.empty()) {
443                 sd.customSet = true;
444                 sd.customSetIndex = FIXED_CUSTOM_SET3;
445             } else if (!plData.descriptorSetLayouts[FIXED_CUSTOM_SET1].bindings.empty()) {
446                 // compatibility set for old engine version
447                 sd.customSet = true;
448                 sd.customSetIndex = FIXED_CUSTOM_SET1;
449             }
450         }
451         sd.pso = renderNodeContextMgr_->GetPsoManager().GetGraphicsPsoHandle(
452             shaderHandle, gfxHandle, plHandle, {}, specialization, GetDynamicStates());
453         sd.shader = shaderHandle;
454     }
455     return sd;
456 }
457 
CreateDescriptorSets()458 void RenderNodeDefaultEnv::CreateDescriptorSets()
459 {
460     auto& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
461     {
462         // automatic calculation
463         const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
464         const DescriptorCounts dc = renderNodeUtil.GetDescriptorCounts(defaultShaderData_.plData);
465         descriptorSetMgr.ResetAndReserve(dc);
466     }
467     {
468         const uint32_t set = 3U;
469         const RenderHandle descriptorSetHandle = descriptorSetMgr.CreateDescriptorSet(set, defaultShaderData_.plData);
470         builtInSet3_ = descriptorSetMgr.CreateDescriptorSetBinder(
471             descriptorSetHandle, defaultShaderData_.plData.descriptorSetLayouts[set].bindings);
472     }
473 }
474 
UpdatePostProcessConfiguration()475 void RenderNodeDefaultEnv::UpdatePostProcessConfiguration()
476 {
477     if (jsonInputs_.nodeFlags & RenderSceneFlagBits::RENDER_SCENE_DIRECT_POST_PROCESS_BIT) {
478         if (!jsonInputs_.renderDataStore.dataStoreName.empty()) {
479             auto const& dsMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
480             if (const IRenderDataStore* ds = dsMgr.GetRenderDataStore(jsonInputs_.renderDataStore.dataStoreName); ds) {
481                 if (jsonInputs_.renderDataStore.typeName == POST_PROCESS_DATA_STORE_TYPE_NAME) {
482                     auto const dataStore = static_cast<const IRenderDataStorePod*>(ds);
483                     auto const dataView = dataStore->Get(jsonInputs_.renderDataStore.configurationName);
484                     if (dataView.data() && (dataView.size_bytes() == sizeof(PostProcessConfiguration))) {
485                         const PostProcessConfiguration* data = (const PostProcessConfiguration*)dataView.data();
486                         currentRenderPPConfiguration_ =
487                             renderNodeContextMgr_->GetRenderNodeUtil().GetRenderPostProcessConfiguration(*data);
488                         currentRenderPPConfiguration_.flags.x =
489                             (currentRenderPPConfiguration_.flags.x & POST_PROCESS_IMPORTANT_FLAGS_MASK);
490                     }
491                 }
492             }
493         }
494     }
495 }
496 
GetDynamicStates() const497 array_view<const DynamicStateEnum> RenderNodeDefaultEnv::GetDynamicStates() const
498 {
499     if (fsrEnabled_) {
500         return { DYNAMIC_STATES_FSR, countof(DYNAMIC_STATES_FSR) };
501     } else {
502         return { DYNAMIC_STATES, countof(DYNAMIC_STATES) };
503     }
504 }
505 
ParseRenderNodeInputs()506 void RenderNodeDefaultEnv::ParseRenderNodeInputs()
507 {
508     const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil();
509     const auto jsonVal = renderNodeContextMgr_->GetNodeJson();
510     jsonInputs_.renderPass = parserUtil.GetInputRenderPass(jsonVal, "renderPass");
511     jsonInputs_.customCameraName = parserUtil.GetStringValue(jsonVal, "customCameraName");
512     jsonInputs_.customCameraId = parserUtil.GetUintValue(jsonVal, "customCameraId");
513     jsonInputs_.renderDataStore = parserUtil.GetRenderDataStore(jsonVal, "renderDataStore");
514 
515     jsonInputs_.nodeFlags = static_cast<uint32_t>(parserUtil.GetUintValue(jsonVal, "nodeFlags"));
516     if (jsonInputs_.nodeFlags == ~0u) {
517         jsonInputs_.nodeFlags = 0;
518     }
519 
520     const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
521     jsonInputs_.renderSlotId = shaderMgr.GetRenderSlotId(parserUtil.GetStringValue(jsonVal, "renderSlot"));
522     jsonInputs_.shaderRenderSlotMultiviewId =
523         shaderMgr.GetRenderSlotId(parserUtil.GetStringValue(jsonVal, "shaderMultiviewRenderSlot"));
524     if (jsonInputs_.renderSlotId == ~0U) {
525         jsonInputs_.renderSlotId =
526             shaderMgr.GetRenderSlotId(DefaultMaterialShaderConstants::RENDER_SLOT_FORWARD_ENVIRONMENT);
527     }
528     if (jsonInputs_.shaderRenderSlotMultiviewId == ~0U) {
529         jsonInputs_.shaderRenderSlotMultiviewId =
530             shaderMgr.GetRenderSlotId(DefaultMaterialShaderConstants::RENDER_SLOT_FORWARD_ENVIRONMENT + "_MV");
531     }
532 
533     EvaluateFogBits();
534 
535     const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
536     inputRenderPass_ = renderNodeUtil.CreateInputRenderPass(jsonInputs_.renderPass);
537     if ((inputRenderPass_.fragmentShadingRateAttachmentIndex < inputRenderPass_.attachments.size()) &&
538         RenderHandleUtil::IsValid(
539             inputRenderPass_.attachments[inputRenderPass_.fragmentShadingRateAttachmentIndex].handle)) {
540         fsrEnabled_ = true;
541     }
542     jsonInputs_.hasChangeableRenderPassHandles = renderNodeUtil.HasChangeableResources(jsonInputs_.renderPass);
543 
544     if (jsonInputs_.customCameraId != INVALID_CAM_ID) {
545         cameraName_ = to_string(jsonInputs_.customCameraId);
546     } else if (!(jsonInputs_.customCameraName.empty())) {
547         cameraName_ = jsonInputs_.customCameraName;
548     }
549 }
550 
ResetRenderSlotData(const bool enableMultiview)551 void RenderNodeDefaultEnv::ResetRenderSlotData(const bool enableMultiview)
552 {
553     // can be reset to multi-view usage or reset back to default usage
554     if (enableMultiView_ != enableMultiview) {
555         enableMultiView_ = enableMultiview;
556         const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
557         defaultShaderData_ = {};
558         const IShaderManager::RenderSlotData shaderRsd = shaderMgr.GetRenderSlotData(jsonInputs_.renderSlotId);
559         defaultShaderData_.shader = shaderRsd.shader.GetHandle();
560         defaultShaderData_.pl = shaderRsd.pipelineLayout.GetHandle();
561         defaultShaderData_.plData = shaderMgr.GetPipelineLayout(defaultShaderData_.pl);
562         if (enableMultiView_) {
563             const IShaderManager::RenderSlotData shaderRsdMv =
564                 shaderMgr.GetRenderSlotData(jsonInputs_.shaderRenderSlotMultiviewId);
565             defaultShaderData_.shader = shaderRsdMv.shader.GetHandle();
566         }
567     }
568 }
569 
EvaluateFogBits()570 void RenderNodeDefaultEnv::EvaluateFogBits()
571 {
572     // if no explicit bits set we check default render slot usages
573     if ((jsonInputs_.nodeFlags & (RENDER_SCENE_ENABLE_FOG_BIT | RENDER_SCENE_DISABLE_FOG_BIT)) == 0) {
574         jsonInputs_.nodeFlags |= RenderSceneFlagBits::RENDER_SCENE_ENABLE_FOG_BIT;
575     }
576 }
577 
578 // for plugin / factory interface
Create()579 RENDER_NS::IRenderNode* RenderNodeDefaultEnv::Create()
580 {
581     return new RenderNodeDefaultEnv();
582 }
583 
Destroy(IRenderNode * instance)584 void RenderNodeDefaultEnv::Destroy(IRenderNode* instance)
585 {
586     delete static_cast<RenderNodeDefaultEnv*>(instance);
587 }
588 CORE3D_END_NAMESPACE()
589