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