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