• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "render_node_scene_util.h"
17 
18 #include <algorithm>
19 
20 #include <3d/render/intf_render_data_store_default_camera.h>
21 #include <3d/render/intf_render_data_store_default_material.h>
22 #include <3d/render/intf_render_data_store_default_scene.h>
23 #include <3d/render/render_data_defines_3d.h>
24 #include <base/containers/vector.h>
25 #include <base/math/matrix_util.h>
26 #include <core/implementation_uids.h>
27 #include <core/log.h>
28 #include <core/namespace.h>
29 #include <core/plugin/intf_plugin_register.h>
30 #include <core/util/intf_frustum_util.h>
31 #include <render/datastore/intf_render_data_store_manager.h>
32 #include <render/device/intf_gpu_resource_manager.h>
33 #include <render/device/pipeline_state_desc.h>
34 #include <render/nodecontext/intf_render_node.h>
35 #include <render/nodecontext/intf_render_node_context_manager.h>
36 #include <render/nodecontext/intf_render_node_util.h>
37 
38 #include "render/datastore/render_data_store_default_material.h"
39 
40 CORE3D_BEGIN_NAMESPACE()
41 using namespace BASE_NS;
42 using namespace CORE_NS;
43 using namespace RENDER_NS;
44 
45 namespace {
operator <(const SlotSubmeshIndex & lhs,const SlotSubmeshIndex & rhs)46 inline bool operator<(const SlotSubmeshIndex& lhs, const SlotSubmeshIndex& rhs)
47 {
48     if (lhs.sortLayerKey < rhs.sortLayerKey) {
49         return true;
50     } else if (lhs.sortLayerKey == rhs.sortLayerKey) {
51         return (lhs.sortKey < rhs.sortKey);
52     } else {
53         return false;
54     }
55 }
56 
operator >(const SlotSubmeshIndex & lhs,const SlotSubmeshIndex & rhs)57 inline bool operator>(const SlotSubmeshIndex& lhs, const SlotSubmeshIndex& rhs)
58 {
59     if (lhs.sortLayerKey < rhs.sortLayerKey) {
60         return true;
61     } else if (lhs.sortLayerKey == rhs.sortLayerKey) {
62         return (lhs.sortKey > rhs.sortKey);
63     } else {
64         return false;
65     }
66 }
67 
68 template<class T>
69 struct Less {
operator ()__anon823ff73f0111::Less70     constexpr bool operator()(const T& lhs, const T& rhs) const
71     {
72         return lhs < rhs;
73     }
74 };
75 
76 template<class T>
77 struct Greater {
operator ()__anon823ff73f0111::Greater78     constexpr bool operator()(const T& lhs, const T& rhs) const
79     {
80         return lhs > rhs;
81     }
82 };
83 
UpdateRenderArea(const Math::Vec4 & scissor,RenderPassDesc::RenderArea & renderArea)84 void UpdateRenderArea(const Math::Vec4& scissor, RenderPassDesc::RenderArea& renderArea)
85 {
86     // prevent larger than image render area
87     if (scissor.x >= 0.0f && scissor.y >= 0.0f && scissor.z <= 1.0f && scissor.w <= 1.0f) {
88         const float fWidth = static_cast<float>(renderArea.extentWidth);
89         const float fHeight = static_cast<float>(renderArea.extentHeight);
90 
91         const float offsetX = (fWidth * scissor.x);
92         const float offsetY = (fHeight * scissor.y);
93         const float extentWidth = (fWidth * scissor.z);
94         const float extentHeight = (fHeight * scissor.w);
95 
96         renderArea = {
97             static_cast<int32_t>(offsetX),
98             static_cast<int32_t>(offsetY),
99             static_cast<uint32_t>(extentWidth),
100             static_cast<uint32_t>(extentHeight),
101         };
102     }
103 }
104 
UpdateCustomCameraTargets(const RenderCamera & camera,RenderPass & renderPass)105 void UpdateCustomCameraTargets(const RenderCamera& camera, RenderPass& renderPass)
106 {
107     auto& subpassDesc = renderPass.subpassDesc;
108     RenderPassDesc& renderPassDesc = renderPass.renderPassDesc;
109     if ((camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) == 0) {
110         if ((subpassDesc.depthAttachmentCount == 1) && camera.depthTarget) {
111             renderPassDesc.attachmentHandles[subpassDesc.depthAttachmentIndex] = camera.depthTarget.GetHandle();
112         }
113         if ((subpassDesc.colorAttachmentCount >= 1) && camera.colorTargets[0u]) {
114             renderPassDesc.attachmentHandles[subpassDesc.colorAttachmentIndices[0]] =
115                 camera.colorTargets[0u].GetHandle();
116         }
117     }
118 }
119 
UpdateCustomCameraLoadStore(const RenderCamera & camera,RenderPass & renderPass)120 void UpdateCustomCameraLoadStore(const RenderCamera& camera, RenderPass& renderPass)
121 {
122     // NOTE: if clear bits given the camera RNG loadOp is overrided with clear
123     // otherwise the loadOp is the one from RNG
124     auto& subpassDesc = renderPass.subpassDesc;
125     if ((subpassDesc.depthAttachmentCount == 1) &&
126         (subpassDesc.depthAttachmentIndex < PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT)) {
127         auto& attRef = renderPass.renderPassDesc.attachments[subpassDesc.depthAttachmentIndex];
128         if ((camera.flags & RenderCamera::CAMERA_FLAG_CLEAR_DEPTH_BIT)) {
129             attRef.loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_CLEAR;
130             attRef.clearValue.depthStencil = camera.clearDepthStencil;
131         }
132         if (((camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) == 0) &&
133             (camera.flags & RenderCamera::CAMERA_FLAG_OUTPUT_DEPTH_BIT)) {
134             attRef.storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
135         }
136     }
137     for (uint32_t idx = 0; idx < subpassDesc.colorAttachmentCount; ++idx) {
138         if (subpassDesc.colorAttachmentIndices[idx] < PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT) {
139             auto& attRef = renderPass.renderPassDesc.attachments[subpassDesc.colorAttachmentIndices[idx]];
140             if (camera.flags & RenderCamera::CAMERA_FLAG_CLEAR_COLOR_BIT) {
141                 attRef.loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_CLEAR;
142                 attRef.clearValue.color = camera.clearColorValues;
143             }
144         }
145     }
146 }
147 
UpdateCameraFlags(const RenderCamera & camera,RenderPass & renderPass)148 void UpdateCameraFlags(const RenderCamera& camera, RenderPass& renderPass)
149 {
150     // NOTE: does not over write viewmask if it has some special values
151     if (renderPass.subpassDesc.viewMask <= 1U) {
152         if (camera.multiViewCameraCount > 0U) {
153             const uint32_t layerCount = camera.multiViewCameraCount + 1U;
154             renderPass.subpassDesc.viewMask = (1U << layerCount) - 1U;
155         } else if (camera.flags & RenderCamera::CAMERA_FLAG_CUBEMAP_BIT) {
156             renderPass.subpassDesc.viewMask = 0x3F; // all cubemap layers
157         }
158     }
159 }
160 
IsObjectCulled(IFrustumUtil & frustumUtil,const Frustum & camFrustum,const array_view<const Frustum> addFrustums,const RenderSubmesh & submesh)161 bool IsObjectCulled(IFrustumUtil& frustumUtil, const Frustum& camFrustum, const array_view<const Frustum> addFrustums,
162     const RenderSubmesh& submesh)
163 {
164     bool notCulled =
165         frustumUtil.SphereFrustumCollision(camFrustum, submesh.bounds.worldCenter, submesh.bounds.worldRadius);
166     if (!notCulled) {
167         // if culled by main camera check additional cameras
168         for (const auto& fRef : addFrustums) {
169             notCulled =
170                 frustumUtil.SphereFrustumCollision(fRef, submesh.bounds.worldCenter, submesh.bounds.worldRadius);
171             if (notCulled) {
172                 break;
173             }
174         }
175     }
176     return !notCulled;
177 }
178 
GetRenderSlotBaseCullType(const RenderSlotCullType cullType,const RenderCamera & camera)179 inline constexpr RenderSlotCullType GetRenderSlotBaseCullType(
180     const RenderSlotCullType cullType, const RenderCamera& camera)
181 {
182     if (camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_CUBEMAP_BIT) {
183         return RenderSlotCullType::NONE;
184     } else {
185         return cullType;
186     }
187 }
188 } // namespace
189 
GetSceneRenderDataStores(const IRenderNodeContextManager & renderNodeContextMgr,const string_view sceneDataStoreName)190 SceneRenderDataStores RenderNodeSceneUtil::GetSceneRenderDataStores(
191     const IRenderNodeContextManager& renderNodeContextMgr, const string_view sceneDataStoreName)
192 {
193     SceneRenderDataStores stores;
194     stores.dataStoreNameScene = sceneDataStoreName.empty() ? "RenderDataStoreDefaultScene" : sceneDataStoreName;
195     const auto& renderDataStoreMgr = renderNodeContextMgr.GetRenderDataStoreManager();
196     const IRenderDataStoreDefaultScene* dsScene =
197         static_cast<IRenderDataStoreDefaultScene*>(renderDataStoreMgr.GetRenderDataStore(stores.dataStoreNameScene));
198     if (dsScene) {
199         const RenderScene& rs = dsScene->GetScene();
200         stores.dataStoreNameMaterial =
201             rs.dataStoreNameMaterial.empty() ? "RenderDataStoreDefaultMaterial" : rs.dataStoreNameMaterial;
202         stores.dataStoreNameCamera =
203             rs.dataStoreNameCamera.empty() ? "RenderDataStoreDefaultCamera" : rs.dataStoreNameCamera;
204         stores.dataStoreNameLight =
205             rs.dataStoreNameLight.empty() ? "RenderDataStoreDefaultLight" : rs.dataStoreNameLight;
206         stores.dataStoreNameMorph = rs.dataStoreNameMorph.empty() ? "RenderDataStoreMorph" : rs.dataStoreNameMorph;
207         stores.dataStoreNamePrefix = rs.dataStoreNamePrefix;
208     }
209     return stores;
210 }
211 
CreateViewportFromCamera(const RenderCamera & camera)212 ViewportDesc RenderNodeSceneUtil::CreateViewportFromCamera(const RenderCamera& camera)
213 {
214     const float fRenderResX = static_cast<float>(camera.renderResolution.x);
215     const float fRenderResY = static_cast<float>(camera.renderResolution.y);
216 
217     const float offsetX = (fRenderResX * camera.viewport.x);
218     const float offsetY = (fRenderResY * camera.viewport.y);
219     const float extentWidth = (fRenderResX * camera.viewport.z);
220     const float extentHeight = (fRenderResY * camera.viewport.w);
221 
222     return ViewportDesc {
223         offsetX,
224         offsetY,
225         extentWidth,
226         extentHeight,
227         0.0f,
228         1.0f,
229     };
230 }
231 
CreateScissorFromCamera(const RenderCamera & camera)232 ScissorDesc RenderNodeSceneUtil::CreateScissorFromCamera(const RenderCamera& camera)
233 {
234     const float fRenderResX = static_cast<float>(camera.renderResolution.x);
235     const float fRenderResY = static_cast<float>(camera.renderResolution.y);
236 
237     const float offsetX = (fRenderResX * camera.scissor.x);
238     const float offsetY = (fRenderResY * camera.scissor.y);
239     const float extentWidth = (fRenderResX * camera.scissor.z);
240     const float extentHeight = (fRenderResY * camera.scissor.w);
241 
242     return ScissorDesc {
243         static_cast<int32_t>(offsetX),
244         static_cast<int32_t>(offsetY),
245         static_cast<uint32_t>(extentWidth),
246         static_cast<uint32_t>(extentHeight),
247     };
248 }
249 
UpdateRenderPassFromCamera(const RenderCamera & camera,RenderPass & renderPass)250 void RenderNodeSceneUtil::UpdateRenderPassFromCamera(const RenderCamera& camera, RenderPass& renderPass)
251 {
252     renderPass.renderPassDesc.renderArea = { 0, 0, camera.renderResolution.x, camera.renderResolution.y };
253     if (camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_CUSTOM_TARGETS_BIT) {
254         UpdateCustomCameraTargets(camera, renderPass);
255     }
256     // NOTE: UpdateCustomCameraClears(camera, renderPass) is not yet called
257     UpdateRenderArea(camera.scissor, renderPass.renderPassDesc.renderArea);
258     UpdateCameraFlags(camera, renderPass);
259 }
260 
UpdateRenderPassFromCustomCamera(const RenderCamera & camera,const bool isNamedCamera,RenderPass & renderPass)261 void RenderNodeSceneUtil::UpdateRenderPassFromCustomCamera(
262     const RenderCamera& camera, const bool isNamedCamera, RenderPass& renderPass)
263 {
264     renderPass.renderPassDesc.renderArea = { 0, 0, camera.renderResolution.x, camera.renderResolution.y };
265     // NOTE: legacy support is only taken into account when isNamedCamera flag is true
266     if ((camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_CUSTOM_TARGETS_BIT) && isNamedCamera) {
267         UpdateCustomCameraTargets(camera, renderPass);
268     }
269     UpdateCustomCameraLoadStore(camera, renderPass);
270     UpdateRenderArea(camera.scissor, renderPass.renderPassDesc.renderArea);
271     UpdateCameraFlags(camera, renderPass);
272 }
273 
GetRenderSlotSubmeshes(const IRenderDataStoreDefaultCamera & dataStoreCamera,const IRenderDataStoreDefaultMaterial & dataStoreMaterial,const uint32_t cameraIndex,const array_view<const uint32_t> addCameraIndices,const IRenderNodeSceneUtil::RenderSlotInfo & renderSlotInfo,vector<SlotSubmeshIndex> & refSubmeshIndices)274 void RenderNodeSceneUtil::GetRenderSlotSubmeshes(const IRenderDataStoreDefaultCamera& dataStoreCamera,
275     const IRenderDataStoreDefaultMaterial& dataStoreMaterial, const uint32_t cameraIndex,
276     const array_view<const uint32_t> addCameraIndices, const IRenderNodeSceneUtil::RenderSlotInfo& renderSlotInfo,
277     vector<SlotSubmeshIndex>& refSubmeshIndices)
278 {
279     // Get IFrustumUtil from global plugin registry.
280     auto frustumUtil = GetInstance<IFrustumUtil>(UID_FRUSTUM_UTIL);
281     if (!frustumUtil) {
282         return;
283     }
284 
285     // 64 bit sorting key should have
286     // material hash with:
287     // shader, materialIndex, meshId, and depth
288 
289     double camSortCoefficient = 1000.0;
290     Math::Mat4X4 camView { Math::IDENTITY_4X4 };
291     uint64_t camLayerMask { RenderSceneDataConstants::INVALID_ID };
292     Frustum camFrustum;
293     const auto& cameras = dataStoreCamera.GetCameras();
294     const uint32_t maxCameraCount = static_cast<uint32_t>(cameras.size());
295     RenderSlotCullType rsCullType = renderSlotInfo.cullType;
296     // process first camera
297     if (cameraIndex < maxCameraCount) {
298         camView = cameras[cameraIndex].matrices.view;
299         const float camZFar = Math::max(0.01f, cameras[cameraIndex].zFar);
300         // max uint coefficient for sorting
301         camSortCoefficient = double(4294967295.0) / double(camZFar); // 4294967295.0: max double value
302         camLayerMask = cameras[cameraIndex].layerMask;
303         rsCullType = GetRenderSlotBaseCullType(rsCullType, cameras[cameraIndex]);
304         if (rsCullType == RenderSlotCullType::VIEW_FRUSTUM_CULL) {
305             camFrustum =
306                 frustumUtil->CreateFrustum(cameras[cameraIndex].matrices.proj * cameras[cameraIndex].matrices.view);
307         }
308     }
309     vector<Frustum> addFrustums;
310     if (rsCullType == RenderSlotCullType::VIEW_FRUSTUM_CULL) {
311         addFrustums.reserve(addCameraIndices.size());
312         for (const auto& indexRef : addCameraIndices) {
313             if (indexRef < maxCameraCount) {
314                 addFrustums.push_back(
315                     frustumUtil->CreateFrustum(cameras[indexRef].matrices.proj * cameras[indexRef].matrices.view));
316             }
317         }
318     }
319 
320     constexpr uint64_t maxUDepth = RenderDataStoreDefaultMaterial::SLOT_SORT_MAX_DEPTH;
321     constexpr uint64_t sDepthShift = RenderDataStoreDefaultMaterial::SLOT_SORT_DEPTH_SHIFT;
322     constexpr uint64_t sRenderMask = RenderDataStoreDefaultMaterial::SLOT_SORT_HASH_MASK;
323     constexpr uint64_t sRenderShift = RenderDataStoreDefaultMaterial::SLOT_SORT_HASH_SHIFT;
324 
325     // NOTE: material sort should be based on PSO not shader handle
326     const auto& slotSubmeshIndices = dataStoreMaterial.GetSlotSubmeshIndices(renderSlotInfo.id);
327     const auto& slotSubmeshMatData = dataStoreMaterial.GetSlotSubmeshMaterialData(renderSlotInfo.id);
328     const auto& submeshes = dataStoreMaterial.GetSubmeshes();
329 
330     refSubmeshIndices.clear();
331     refSubmeshIndices.reserve(slotSubmeshIndices.size());
332     for (size_t idx = 0; idx < slotSubmeshIndices.size(); ++idx) {
333         const uint32_t submeshIndex = slotSubmeshIndices[idx];
334         const auto& submesh = submeshes[submeshIndex];
335         const bool notCulled = (rsCullType != RenderSlotCullType::VIEW_FRUSTUM_CULL) ||
336                                (!IsObjectCulled(*frustumUtil, camFrustum, addFrustums, submesh));
337         const auto& submeshMatData = slotSubmeshMatData[idx];
338         const bool discardedMat = (submeshMatData.renderMaterialFlags & renderSlotInfo.materialDiscardFlags);
339         if ((camLayerMask & submesh.layers.layerMask) && notCulled && (!discardedMat)) {
340             const Math::Vec4 pos = (camView * Math::Vec4(submesh.bounds.worldCenter, 1.0f));
341             const float zVal = Math::abs(pos.z);
342             uint64_t sortKey = Math::min(maxUDepth, static_cast<uint64_t>(double(zVal) * camSortCoefficient));
343             if (renderSlotInfo.sortType == RenderSlotSortType::BY_MATERIAL) {
344                 sortKey |= (((uint64_t)submeshMatData.renderSortHash & sRenderMask) << sRenderShift);
345             } else {
346                 sortKey = (sortKey << sDepthShift) | ((uint64_t)slotSubmeshMatData[idx].renderSortHash & sRenderMask);
347             }
348             refSubmeshIndices.push_back(
349                 SlotSubmeshIndex { (uint32_t)submeshIndex, submeshMatData.combinedRenderSortLayer, sortKey,
350                     submeshMatData.renderSortHash, submeshMatData.shader, submeshMatData.gfxState });
351         }
352     }
353 
354     // front-to-back and by-material render layer sort is 0 -> 63
355     // back-to-front render layer sort is 63 -> 0
356     if (renderSlotInfo.sortType == RenderSlotSortType::FRONT_TO_BACK ||
357         renderSlotInfo.sortType == RenderSlotSortType::BY_MATERIAL) {
358         std::sort(refSubmeshIndices.begin(), refSubmeshIndices.end(), Less<SlotSubmeshIndex>());
359     } else if (renderSlotInfo.sortType == RenderSlotSortType::BACK_TO_FRONT) {
360         std::sort(refSubmeshIndices.begin(), refSubmeshIndices.end(), Greater<SlotSubmeshIndex>());
361     }
362 }
363 
GetSceneBufferHandles(RENDER_NS::IRenderNodeContextManager & renderNodeContextMgr,const BASE_NS::string_view sceneName)364 SceneBufferHandles RenderNodeSceneUtil::GetSceneBufferHandles(
365     RENDER_NS::IRenderNodeContextManager& renderNodeContextMgr, const BASE_NS::string_view sceneName)
366 {
367     SceneBufferHandles buffers;
368     const auto& gpuMgr = renderNodeContextMgr.GetGpuResourceManager();
369     buffers.camera = gpuMgr.GetBufferHandle(sceneName + DefaultMaterialCameraConstants::CAMERA_DATA_BUFFER_NAME);
370     buffers.material = gpuMgr.GetBufferHandle(sceneName + DefaultMaterialMaterialConstants::MATERIAL_DATA_BUFFER_NAME);
371     buffers.materialTransform =
372         gpuMgr.GetBufferHandle(sceneName + DefaultMaterialMaterialConstants::MATERIAL_TRANSFORM_DATA_BUFFER_NAME);
373     buffers.materialCustom =
374         gpuMgr.GetBufferHandle(sceneName + DefaultMaterialMaterialConstants::MATERIAL_USER_DATA_BUFFER_NAME);
375     buffers.mesh = gpuMgr.GetBufferHandle(sceneName + DefaultMaterialMaterialConstants::MESH_DATA_BUFFER_NAME);
376     buffers.skinJoint = gpuMgr.GetBufferHandle(sceneName + DefaultMaterialMaterialConstants::SKIN_DATA_BUFFER_NAME);
377 
378     const RenderHandle defaultBuffer = gpuMgr.GetBufferHandle("CORE_DEFAULT_GPU_BUFFER");
379     auto checkValidity = [](const RenderHandle defaultBuffer, bool& valid, RenderHandle& buffer) {
380         if (!RenderHandleUtil::IsValid(buffer)) {
381             valid = false;
382             buffer = defaultBuffer;
383         }
384     };
385     bool valid = true;
386     checkValidity(defaultBuffer, valid, buffers.camera);
387     checkValidity(defaultBuffer, valid, buffers.material);
388     checkValidity(defaultBuffer, valid, buffers.materialTransform);
389     checkValidity(defaultBuffer, valid, buffers.materialCustom);
390     checkValidity(defaultBuffer, valid, buffers.mesh);
391     checkValidity(defaultBuffer, valid, buffers.skinJoint);
392     if (!valid) {
393         CORE_LOG_E(
394             "RN: %s, invalid configuration, not all scene buffers not found.", renderNodeContextMgr.GetName().data());
395     }
396     return buffers;
397 }
398 
GetSceneCameraBufferHandles(RENDER_NS::IRenderNodeContextManager & renderNodeContextMgr,const BASE_NS::string_view sceneName,const BASE_NS::string_view cameraName)399 SceneCameraBufferHandles RenderNodeSceneUtil::GetSceneCameraBufferHandles(
400     RENDER_NS::IRenderNodeContextManager& renderNodeContextMgr, const BASE_NS::string_view sceneName,
401     const BASE_NS::string_view cameraName)
402 {
403     SceneCameraBufferHandles buffers;
404     const auto& gpuMgr = renderNodeContextMgr.GetGpuResourceManager();
405     buffers.generalData = gpuMgr.GetBufferHandle(
406         sceneName + DefaultMaterialCameraConstants::CAMERA_GENERAL_BUFFER_PREFIX_NAME + cameraName);
407     buffers.environment = gpuMgr.GetBufferHandle(
408         sceneName + DefaultMaterialCameraConstants::CAMERA_ENVIRONMENT_BUFFER_PREFIX_NAME + cameraName);
409     buffers.fog =
410         gpuMgr.GetBufferHandle(sceneName + DefaultMaterialCameraConstants::CAMERA_FOG_BUFFER_PREFIX_NAME + cameraName);
411     buffers.postProcess = gpuMgr.GetBufferHandle(
412         sceneName + DefaultMaterialCameraConstants::CAMERA_POST_PROCESS_BUFFER_PREFIX_NAME + cameraName);
413 
414     buffers.light = gpuMgr.GetBufferHandle(
415         sceneName + DefaultMaterialCameraConstants::CAMERA_LIGHT_BUFFER_PREFIX_NAME + cameraName);
416     buffers.lightCluster = gpuMgr.GetBufferHandle(
417         sceneName + DefaultMaterialCameraConstants::CAMERA_LIGHT_CLUSTER_BUFFER_PREFIX_NAME + cameraName);
418 
419     const RenderHandle defaultBuffer = gpuMgr.GetBufferHandle("CORE_DEFAULT_GPU_BUFFER");
420     auto checkValidity = [](const RenderHandle defaultBuffer, bool& valid, RenderHandle& buffer) {
421         if (!RenderHandleUtil::IsValid(buffer)) {
422             valid = false;
423             buffer = defaultBuffer;
424         }
425     };
426     bool valid = true;
427     checkValidity(defaultBuffer, valid, buffers.generalData);
428     checkValidity(defaultBuffer, valid, buffers.environment);
429     checkValidity(defaultBuffer, valid, buffers.fog);
430     checkValidity(defaultBuffer, valid, buffers.postProcess);
431     checkValidity(defaultBuffer, valid, buffers.light);
432     checkValidity(defaultBuffer, valid, buffers.lightCluster);
433     if (!valid) {
434         CORE_LOG_E(
435             "RN: %s, invalid configuration, not all camera buffers found.", renderNodeContextMgr.GetName().data());
436     }
437     return buffers;
438 }
439 
GetSceneCameraImageHandles(RENDER_NS::IRenderNodeContextManager & renderNodeContextMgr,const BASE_NS::string_view sceneName,const BASE_NS::string_view cameraName,const RenderCamera & camera)440 SceneCameraImageHandles RenderNodeSceneUtil::GetSceneCameraImageHandles(
441     RENDER_NS::IRenderNodeContextManager& renderNodeContextMgr, const BASE_NS::string_view sceneName,
442     const BASE_NS::string_view cameraName, const RenderCamera& camera)
443 {
444     SceneCameraImageHandles handles;
445     const auto& gpuMgr = renderNodeContextMgr.GetGpuResourceManager();
446     handles.radianceCubemap = camera.environment.radianceCubemap.GetHandle();
447     if ((!RenderHandleUtil::IsValid(handles.radianceCubemap)) && (camera.environment.multiEnvCount > 0U)) {
448         handles.radianceCubemap =
449             gpuMgr.GetImageHandle(sceneName + DefaultMaterialSceneConstants::ENVIRONMENT_RADIANCE_CUBEMAP_PREFIX_NAME +
450                                   to_hex(camera.environment.id));
451     }
452     if (!RenderHandleUtil::IsValid(handles.radianceCubemap)) {
453         handles.radianceCubemap =
454             gpuMgr.GetImageHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_RADIANCE_CUBEMAP);
455     }
456     return handles;
457 }
458 
GetSceneRenderDataStores(const IRenderNodeContextManager & renderNodeContextMgr,const string_view sceneDataStoreName)459 SceneRenderDataStores RenderNodeSceneUtilImpl::GetSceneRenderDataStores(
460     const IRenderNodeContextManager& renderNodeContextMgr, const string_view sceneDataStoreName)
461 {
462     return RenderNodeSceneUtil::GetSceneRenderDataStores(renderNodeContextMgr, sceneDataStoreName);
463 }
464 
CreateViewportFromCamera(const RenderCamera & camera)465 ViewportDesc RenderNodeSceneUtilImpl::CreateViewportFromCamera(const RenderCamera& camera)
466 {
467     return RenderNodeSceneUtil::CreateViewportFromCamera(camera);
468 }
469 
CreateScissorFromCamera(const RenderCamera & camera)470 ScissorDesc RenderNodeSceneUtilImpl::CreateScissorFromCamera(const RenderCamera& camera)
471 {
472     return RenderNodeSceneUtil::CreateScissorFromCamera(camera);
473 }
474 
UpdateRenderPassFromCamera(const RenderCamera & camera,RenderPass & renderPass)475 void RenderNodeSceneUtilImpl::UpdateRenderPassFromCamera(const RenderCamera& camera, RenderPass& renderPass)
476 {
477     return RenderNodeSceneUtil::UpdateRenderPassFromCamera(camera, renderPass);
478 }
479 
UpdateRenderPassFromCustomCamera(const RenderCamera & camera,const bool isNamedCamera,RenderPass & renderPass)480 void RenderNodeSceneUtilImpl::UpdateRenderPassFromCustomCamera(
481     const RenderCamera& camera, const bool isNamedCamera, RenderPass& renderPass)
482 {
483     return RenderNodeSceneUtil::UpdateRenderPassFromCustomCamera(camera, isNamedCamera, renderPass);
484 }
485 
GetRenderSlotSubmeshes(const IRenderDataStoreDefaultCamera & dataStoreCamera,const IRenderDataStoreDefaultMaterial & dataStoreMaterial,const uint32_t cameraId,const IRenderNodeSceneUtil::RenderSlotInfo & renderSlotInfo,vector<SlotSubmeshIndex> & refSubmeshIndices)486 void RenderNodeSceneUtilImpl::GetRenderSlotSubmeshes(const IRenderDataStoreDefaultCamera& dataStoreCamera,
487     const IRenderDataStoreDefaultMaterial& dataStoreMaterial, const uint32_t cameraId,
488     const IRenderNodeSceneUtil::RenderSlotInfo& renderSlotInfo, vector<SlotSubmeshIndex>& refSubmeshIndices)
489 {
490     return RenderNodeSceneUtil::GetRenderSlotSubmeshes(
491         dataStoreCamera, dataStoreMaterial, cameraId, {}, renderSlotInfo, refSubmeshIndices);
492 }
493 
GetRenderSlotSubmeshes(const IRenderDataStoreDefaultCamera & dataStoreCamera,const IRenderDataStoreDefaultMaterial & dataStoreMaterial,const uint32_t cameraIndex,const array_view<const uint32_t> addCameraIndices,const IRenderNodeSceneUtil::RenderSlotInfo & renderSlotInfo,vector<SlotSubmeshIndex> & refSubmeshIndices)494 void RenderNodeSceneUtilImpl::GetRenderSlotSubmeshes(const IRenderDataStoreDefaultCamera& dataStoreCamera,
495     const IRenderDataStoreDefaultMaterial& dataStoreMaterial, const uint32_t cameraIndex,
496     const array_view<const uint32_t> addCameraIndices, const IRenderNodeSceneUtil::RenderSlotInfo& renderSlotInfo,
497     vector<SlotSubmeshIndex>& refSubmeshIndices)
498 {
499     return RenderNodeSceneUtil::GetRenderSlotSubmeshes(
500         dataStoreCamera, dataStoreMaterial, cameraIndex, addCameraIndices, renderSlotInfo, refSubmeshIndices);
501 }
502 
GetSceneBufferHandles(IRenderNodeContextManager & renderNodeContextMgr,const string_view sceneName)503 SceneBufferHandles RenderNodeSceneUtilImpl::GetSceneBufferHandles(
504     IRenderNodeContextManager& renderNodeContextMgr, const string_view sceneName)
505 {
506     return RenderNodeSceneUtil::GetSceneBufferHandles(renderNodeContextMgr, sceneName);
507 }
508 
GetSceneCameraBufferHandles(IRenderNodeContextManager & renderNodeContextMgr,const string_view sceneName,const string_view cameraName)509 SceneCameraBufferHandles RenderNodeSceneUtilImpl::GetSceneCameraBufferHandles(
510     IRenderNodeContextManager& renderNodeContextMgr, const string_view sceneName, const string_view cameraName)
511 {
512     return RenderNodeSceneUtil::GetSceneCameraBufferHandles(renderNodeContextMgr, sceneName, cameraName);
513 }
514 
GetSceneCameraImageHandles(RENDER_NS::IRenderNodeContextManager & renderNodeContextMgr,const BASE_NS::string_view sceneName,const BASE_NS::string_view cameraName,const RenderCamera & camera)515 SceneCameraImageHandles RenderNodeSceneUtilImpl::GetSceneCameraImageHandles(
516     RENDER_NS::IRenderNodeContextManager& renderNodeContextMgr, const BASE_NS::string_view sceneName,
517     const BASE_NS::string_view cameraName, const RenderCamera& camera)
518 {
519     return RenderNodeSceneUtil::GetSceneCameraImageHandles(renderNodeContextMgr, sceneName, cameraName, camera);
520 }
521 
GetInterface(const Uid & uid) const522 const IInterface* RenderNodeSceneUtilImpl::GetInterface(const Uid& uid) const
523 {
524     if ((uid == IRenderNodeSceneUtil::UID) || (uid == IInterface::UID)) {
525         return this;
526     }
527     return nullptr;
528 }
529 
GetInterface(const Uid & uid)530 IInterface* RenderNodeSceneUtilImpl::GetInterface(const Uid& uid)
531 {
532     if ((uid == IRenderNodeSceneUtil::UID) || (uid == IInterface::UID)) {
533         return this;
534     }
535     return nullptr;
536 }
537 
Ref()538 void RenderNodeSceneUtilImpl::Ref() {}
539 
Unref()540 void RenderNodeSceneUtilImpl::Unref() {}
541 CORE3D_END_NAMESPACE()
542