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