• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "render_node_default_camera_controller.h"
17 
18 #if (CORE3D_VALIDATION_ENABLED == 1)
19 #include <cinttypes>
20 #include <string>
21 #endif
22 
23 #include <3d/implementation_uids.h>
24 #include <3d/intf_graphics_context.h>
25 #include <3d/render/default_material_constants.h>
26 #include <3d/render/intf_render_data_store_default_camera.h>
27 #include <3d/render/intf_render_data_store_default_light.h>
28 #include <3d/render/intf_render_data_store_default_material.h>
29 #include <3d/render/intf_render_data_store_default_scene.h>
30 #include <3d/shaders/common/3d_dm_structures_common.h>
31 #include <base/containers/array_view.h>
32 #include <base/containers/fixed_string.h>
33 #include <base/containers/string.h>
34 #include <base/containers/vector.h>
35 #include <base/math/mathf.h>
36 #include <base/math/matrix_util.h>
37 #include <base/math/vector.h>
38 #include <core/log.h>
39 #include <core/namespace.h>
40 #include <core/plugin/intf_class_register.h>
41 #include <render/datastore/intf_render_data_store.h>
42 #include <render/datastore/intf_render_data_store_manager.h>
43 #include <render/datastore/intf_render_data_store_pod.h>
44 #include <render/datastore/render_data_store_render_pods.h>
45 #include <render/device/gpu_resource_desc.h>
46 #include <render/device/intf_gpu_resource_manager.h>
47 #include <render/device/intf_shader_manager.h>
48 #include <render/intf_render_context.h>
49 #include <render/nodecontext/intf_node_context_descriptor_set_manager.h>
50 #include <render/nodecontext/intf_node_context_pso_manager.h>
51 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
52 #include <render/nodecontext/intf_render_command_list.h>
53 #include <render/nodecontext/intf_render_node_context_manager.h>
54 #include <render/nodecontext/intf_render_node_graph_share_manager.h>
55 #include <render/nodecontext/intf_render_node_parser_util.h>
56 #include <render/nodecontext/intf_render_node_util.h>
57 #include <render/render_data_structures.h>
58 
59 #include "render/datastore/render_data_store_weather.h"
60 // NOTE: do not include in header
61 #include "render_light_helper.h"
62 
63 namespace {
64 #include <render/shaders/common/render_post_process_common.h>
65 } // namespace
66 
67 CORE3D_BEGIN_NAMESPACE()
68 using namespace BASE_NS;
69 using namespace RENDER_NS;
70 
71 namespace {
72 constexpr bool ENABLE_RT { true };
73 
74 constexpr bool USE_IMMUTABLE_SAMPLERS { false };
75 constexpr float CUBE_MAP_LOD_COEFF { 8.0f };
76 constexpr string_view POD_DATA_STORE_NAME { "RenderDataStorePod" };
77 
ValidateRenderCamera(RenderCamera & camera)78 void ValidateRenderCamera(RenderCamera& camera)
79 {
80     if (camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) {
81         if (camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_MSAA_BIT) {
82             camera.flags = camera.flags & (~RenderCamera::CameraFlagBits::CAMERA_FLAG_MSAA_BIT);
83 #if (CORE3D_VALIDATION_ENABLED == 1)
84             CORE_LOG_ONCE_I("valid_r_c_" + to_string(camera.id),
85                 "MSAA flag with deferred pipeline dropped (cam id %" PRIu64 ")", camera.id);
86 #endif
87         }
88     }
89 #if (CORE3D_VALIDATION_ENABLED == 1)
90     if (camera.id == RenderSceneDataConstants::INVALID_ID) {
91         CORE_LOG_ONCE_I("valid_r_c_id" + to_string(camera.id), "Invalid camera id (cam id %" PRIu64 ")", camera.id);
92     }
93 #endif
94 }
95 
GetValidColorFormat(const IRenderNodeGpuResourceManager & gpuResourceMgr,const Format format)96 Format GetValidColorFormat(const IRenderNodeGpuResourceManager& gpuResourceMgr, const Format format)
97 {
98     Format outFormat = format;
99     const auto formatProperties = gpuResourceMgr.GetFormatProperties(format);
100     if (((formatProperties.optimalTilingFeatures & CORE_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) == 0) ||
101         ((formatProperties.optimalTilingFeatures & CORE_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)) {
102         outFormat = Format::BASE_FORMAT_R8G8B8A8_SRGB;
103 #if (CORE3D_VALIDATION_ENABLED == 1)
104         CORE_LOG_W("CORE_VALIDATION: not supported camera color format %u, using BASE_FORMAT_R8G8B8A8_SRGB", outFormat);
105 #endif
106     }
107     return outFormat;
108 }
109 
GetValidDepthFormat(const IRenderNodeGpuResourceManager & gpuResourceMgr,const Format format)110 Format GetValidDepthFormat(const IRenderNodeGpuResourceManager& gpuResourceMgr, const Format format)
111 {
112     Format outFormat = format;
113     const auto formatProperties = gpuResourceMgr.GetFormatProperties(format);
114     if ((formatProperties.optimalTilingFeatures & CORE_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0) {
115         outFormat = Format::BASE_FORMAT_D32_SFLOAT;
116 #if (CORE3D_VALIDATION_ENABLED == 1)
117         CORE_LOG_W("CORE_VALIDATION: not supported camera depth format %u, using BASE_FORMAT_D32_SFLOAT", outFormat);
118 #endif
119     }
120     return outFormat;
121 }
122 
123 constexpr GpuImageDesc OUTPUT_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D, BASE_FORMAT_R8G8B8A8_SRGB,
124     CORE_IMAGE_TILING_OPTIMAL,
125     CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | CORE_IMAGE_USAGE_SAMPLED_BIT,
126     CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0U, CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U,
127     CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
128 constexpr GpuImageDesc COLOR_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D,
129     BASE_FORMAT_R16G16B16A16_SFLOAT, CORE_IMAGE_TILING_OPTIMAL,
130     CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | CORE_IMAGE_USAGE_SAMPLED_BIT,
131     CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0U, CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U,
132     CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
133 constexpr GpuImageDesc VELOCITY_NORMAL_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D,
134     BASE_FORMAT_R16G16B16A16_SFLOAT, CORE_IMAGE_TILING_OPTIMAL,
135     CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
136     CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0U,
137     CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U, CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
138 constexpr GpuImageDesc HISTORY_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D,
139     BASE_FORMAT_B10G11R11_UFLOAT_PACK32, CORE_IMAGE_TILING_OPTIMAL,
140     CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | CORE_IMAGE_USAGE_SAMPLED_BIT,
141     CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0U, CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U,
142     CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
143 constexpr GpuImageDesc BASE_COLOR_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D, BASE_FORMAT_R8G8B8A8_SRGB,
144     CORE_IMAGE_TILING_OPTIMAL,
145     CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
146         CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
147     CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0U,
148     CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U, CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
149 constexpr GpuImageDesc MATERIAL_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D, BASE_FORMAT_R8G8B8A8_UNORM,
150     CORE_IMAGE_TILING_OPTIMAL,
151     CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
152         CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
153     CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0U,
154     CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U, CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
155 
156 constexpr GpuImageDesc DEPTH_DEFAULT_DESC { CORE_IMAGE_TYPE_2D, CORE_IMAGE_VIEW_TYPE_2D, BASE_FORMAT_D32_SFLOAT,
157     CORE_IMAGE_TILING_OPTIMAL,
158     CORE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
159         CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
160     CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0U,
161     CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, 1U, 1U, 1U, 1U, 1U, CORE_SAMPLE_COUNT_1_BIT, ComponentMapping {} };
162 
GetShadowBufferNodeData(IRenderNodeGpuResourceManager & gpuResourceMgr,const string_view sceneName)163 RenderNodeDefaultCameraController::ShadowBuffers GetShadowBufferNodeData(
164     IRenderNodeGpuResourceManager& gpuResourceMgr, const string_view sceneName)
165 {
166     RenderNodeDefaultCameraController::ShadowBuffers sb;
167     sb.vsmSamplerHandle =
168         gpuResourceMgr.GetSamplerHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_VSM_SHADOW_SAMPLER);
169     sb.pcfSamplerHandle =
170         gpuResourceMgr.GetSamplerHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_PCF_SHADOW_SAMPLER);
171 
172     sb.depthHandle =
173         gpuResourceMgr.GetImageHandle(sceneName + DefaultMaterialLightingConstants::SHADOW_DEPTH_BUFFER_NAME);
174     sb.vsmColorHandle =
175         gpuResourceMgr.GetImageHandle(sceneName + DefaultMaterialLightingConstants::SHADOW_VSM_COLOR_BUFFER_NAME);
176     if (!RenderHandleUtil::IsValid(sb.depthHandle)) {
177         sb.depthHandle = gpuResourceMgr.GetImageHandle("CORE_DEFAULT_GPU_IMAGE_WHITE");
178     }
179     if (!RenderHandleUtil::IsValid(sb.vsmColorHandle)) {
180         sb.vsmColorHandle = gpuResourceMgr.GetImageHandle("CORE_DEFAULT_GPU_IMAGE");
181     }
182 
183     return sb;
184 }
185 
ValidateColorDesc(const IRenderNodeGpuResourceManager & gpuResourceMgr,const GpuImageDesc & input,const bool bilinearSampling,GpuImageDesc & desc)186 void ValidateColorDesc(const IRenderNodeGpuResourceManager& gpuResourceMgr, const GpuImageDesc& input,
187     const bool bilinearSampling, GpuImageDesc& desc)
188 {
189     desc.imageType = input.imageType;
190     desc.imageViewType = input.imageViewType;
191     desc.imageTiling = input.imageTiling;
192     if (desc.format == BASE_FORMAT_UNDEFINED) {
193         desc.format = input.format;
194     }
195     if (desc.usageFlags == 0) {
196         desc.usageFlags = input.usageFlags;
197     }
198     if (desc.memoryPropertyFlags == 0) {
199         desc.memoryPropertyFlags = input.memoryPropertyFlags;
200     }
201     if (desc.createFlags == 0) {
202         desc.createFlags = input.createFlags;
203     }
204     if (desc.engineCreationFlags == 0) {
205         desc.engineCreationFlags = input.engineCreationFlags;
206     }
207     desc.width = Math::max(desc.width, input.width);
208     desc.height = Math::max(desc.height, input.height);
209     desc.depth = Math::max(desc.depth, input.depth);
210 
211     desc.mipCount = Math::max(desc.mipCount, input.mipCount);
212     desc.layerCount = Math::max(desc.layerCount, input.layerCount);
213 
214     if ((desc.layerCount == 1U) && (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D_ARRAY)) {
215         desc.imageViewType = CORE_IMAGE_VIEW_TYPE_2D;
216     } else if ((desc.layerCount > 1U) && (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D)) {
217         desc.imageViewType = CORE_IMAGE_VIEW_TYPE_2D_ARRAY;
218     }
219     if (desc.sampleCountFlags == 0) {
220         desc.sampleCountFlags = CORE_SAMPLE_COUNT_1_BIT;
221     }
222 
223     if (bilinearSampling) {
224         desc.format = GetValidColorFormat(gpuResourceMgr, desc.format);
225     }
226 }
227 
GetImageViewType(const uint32_t layerCount,const ImageViewType imageViewType)228 ImageViewType GetImageViewType(const uint32_t layerCount, const ImageViewType imageViewType)
229 {
230     if ((layerCount == 1U) && (imageViewType == CORE_IMAGE_VIEW_TYPE_2D_ARRAY)) {
231         return CORE_IMAGE_VIEW_TYPE_2D;
232     } else if ((layerCount > 1U) && (imageViewType == CORE_IMAGE_VIEW_TYPE_2D)) {
233         return CORE_IMAGE_VIEW_TYPE_2D_ARRAY;
234     }
235     return imageViewType;
236 }
237 
ValidateDepthDesc(const IRenderNodeGpuResourceManager & gpuResourceMgr,const GpuImageDesc & input,GpuImageDesc & desc)238 void ValidateDepthDesc(
239     const IRenderNodeGpuResourceManager& gpuResourceMgr, const GpuImageDesc& input, GpuImageDesc& desc)
240 {
241     desc.imageType = input.imageType;
242     desc.imageViewType = input.imageViewType;
243     desc.imageTiling = input.imageTiling;
244     if (desc.format == BASE_FORMAT_UNDEFINED) {
245         desc.format = input.format;
246     }
247     if (desc.usageFlags == 0) {
248         desc.usageFlags = input.usageFlags;
249     }
250     if (desc.memoryPropertyFlags == 0) {
251         desc.memoryPropertyFlags = input.memoryPropertyFlags;
252     }
253     if (desc.createFlags == 0) {
254         desc.createFlags = input.createFlags;
255     }
256     if (desc.engineCreationFlags == 0) {
257         desc.engineCreationFlags = input.engineCreationFlags;
258     }
259     desc.width = Math::max(desc.width, input.width);
260     desc.height = Math::max(desc.height, input.height);
261     desc.depth = Math::max(desc.depth, input.depth);
262 
263     desc.mipCount = Math::max(desc.mipCount, input.mipCount);
264     desc.layerCount = Math::max(desc.layerCount, input.layerCount);
265 
266     if ((desc.layerCount == 1U) && (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D_ARRAY)) {
267         desc.imageViewType = CORE_IMAGE_VIEW_TYPE_2D;
268     } else if ((desc.layerCount > 1U) && (desc.imageViewType == CORE_IMAGE_VIEW_TYPE_2D)) {
269         desc.imageViewType = CORE_IMAGE_VIEW_TYPE_2D_ARRAY;
270     }
271     if (desc.sampleCountFlags == 0) {
272         desc.sampleCountFlags = CORE_SAMPLE_COUNT_1_BIT;
273     }
274 
275     desc.format = GetValidDepthFormat(gpuResourceMgr, desc.format);
276 }
277 
278 struct CreatedTargetHandles {
279     RenderHandle color;
280     RenderHandle depth;
281     RenderHandle colorResolve;
282     RenderHandle colorMsaa;
283     RenderHandle depthMsaa;
284     RenderHandle baseColor;
285     RenderHandle velNor;
286     RenderHandle material;
287 };
288 
FillCreatedTargets(const RenderNodeDefaultCameraController::CreatedTargets & targets)289 CreatedTargetHandles FillCreatedTargets(const RenderNodeDefaultCameraController::CreatedTargets& targets)
290 {
291     return CreatedTargetHandles {
292         targets.outputColor.GetHandle(),
293         targets.depth.GetHandle(),
294         targets.colorResolve.GetHandle(),
295         targets.colorMsaa.GetHandle(),
296         targets.depthMsaa.GetHandle(),
297         targets.baseColor.GetHandle(),
298         targets.velocityNormal.GetHandle(),
299         targets.material.GetHandle(),
300     };
301 }
302 
GetPacked64(const uint64_t value)303 inline constexpr Math::UVec2 GetPacked64(const uint64_t value)
304 {
305     return { static_cast<uint32_t>(value >> 32) & 0xFFFFffff, static_cast<uint32_t>(value & 0xFFFFffff) };
306 }
307 
CreateBaseColorTarget(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const string_view us,const string_view customCamRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & targets)308 void CreateBaseColorTarget(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
309     const string_view us, const string_view customCamRngId,
310     const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
311     RenderNodeDefaultCameraController::CreatedTargets& targets)
312 {
313 #if (CORE3D_VALIDATION_ENABLED == 1)
314     CORE_LOG_I("CORE3D_VALIDATION: creating camera base color target %s", customCamRngId.data());
315 #endif
316     GpuImageDesc desc = cameraResourceSetup.inputImageDescs.output;
317     desc.width = camera.renderResolution.x;
318     desc.height = camera.renderResolution.y;
319     desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
320     targets.outputColor =
321         gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + customCamRngId, desc);
322     targets.imageDescs.output = desc;
323 }
324 
CreateVelocityTarget(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCameraRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)325 void CreateVelocityTarget(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
326     const GpuImageDesc& targetDesc, const string_view us, const string_view customCameraRngId,
327     const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
328     RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
329 {
330     const bool createVelocity = (camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) ||
331                                 (camera.renderPipelineType == RenderCamera::RenderPipelineType::FORWARD);
332     if (createVelocity) {
333         GpuImageDesc desc = cameraResourceSetup.inputImageDescs.velocityNormal;
334         desc.width = targetDesc.width;
335         desc.height = targetDesc.height;
336         desc.layerCount = targetDesc.layerCount;
337         desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
338         // patch even RNG given flags
339         if (camera.flags & RenderCamera::CAMERA_FLAG_OUTPUT_VELOCITY_NORMAL_BIT) {
340             desc.usageFlags |= CORE_IMAGE_USAGE_SAMPLED_BIT;
341             // we cannot have transient and lazy allocation
342             desc.usageFlags &= (~CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT);
343             desc.memoryPropertyFlags &= (~CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT);
344         }
345 #if (CORE3D_VALIDATION_ENABLED == 1)
346         createdTargets.velocityNormal = gpuResourceMgr.Create(
347             us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "VEL_NOR" + customCameraRngId, desc);
348 #else
349         createdTargets.velocityNormal = gpuResourceMgr.Create(createdTargets.velocityNormal, desc);
350 #endif
351         // store
352         createdTargets.imageDescs.velocityNormal = desc;
353     }
354 }
355 
CreateDeferredTargets(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCameraRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)356 void CreateDeferredTargets(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
357     const GpuImageDesc& targetDesc, const string_view us, const string_view customCameraRngId,
358     const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
359     RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
360 {
361     if (camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) {
362         GpuImageDesc desc = cameraResourceSetup.inputImageDescs.baseColor;
363         desc.width = targetDesc.width;
364         desc.height = targetDesc.height;
365         desc.layerCount = targetDesc.layerCount;
366         desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
367 #if (CORE3D_VALIDATION_ENABLED == 1)
368         createdTargets.baseColor = gpuResourceMgr.Create(
369             us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "BC_" + customCameraRngId, desc);
370 #else
371         createdTargets.baseColor = gpuResourceMgr.Create(createdTargets.baseColor, desc);
372 #endif
373         // store
374         createdTargets.imageDescs.baseColor = desc;
375 
376         // create material
377         desc = cameraResourceSetup.inputImageDescs.material;
378         desc.width = targetDesc.width;
379         desc.height = targetDesc.height;
380         desc.layerCount = targetDesc.layerCount;
381 #if (CORE3D_VALIDATION_ENABLED == 1)
382         createdTargets.material = gpuResourceMgr.Create(
383             us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "MAT_" + customCameraRngId, desc);
384 #else
385         createdTargets.material = gpuResourceMgr.Create(createdTargets.material, desc);
386 #endif
387         // store
388         createdTargets.imageDescs.material = desc;
389     }
390 }
391 
CreateHistoryTargets(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCameraRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)392 void CreateHistoryTargets(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
393     const GpuImageDesc& targetDesc, const string_view us, const string_view customCameraRngId,
394     const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
395     RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
396 {
397     if (camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_HISTORY_BIT) {
398         GpuImageDesc desc = cameraResourceSetup.inputImageDescs.history;
399         desc.width = targetDesc.width;
400         desc.height = targetDesc.height;
401         desc.layerCount = targetDesc.layerCount;
402         desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
403 #if (CORE3D_VALIDATION_ENABLED == 1)
404         createdTargets.history[0u] = gpuResourceMgr.Create(
405             us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "HIS0_" + customCameraRngId, desc);
406         createdTargets.history[1u] = gpuResourceMgr.Create(
407             us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "HIS1_" + customCameraRngId, desc);
408 #else
409         createdTargets.history[0u] = gpuResourceMgr.Create(createdTargets.history[0u], desc);
410         createdTargets.history[1u] = gpuResourceMgr.Create(createdTargets.history[1u], desc);
411 #endif
412 
413         // store
414         createdTargets.imageDescs.history = desc;
415     }
416 }
417 
CreateColorTargets(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCamRngId,const RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)418 void CreateColorTargets(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
419     const GpuImageDesc& targetDesc, const string_view us, const string_view customCamRngId,
420     const RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
421     RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
422 {
423 #if (CORE3D_VALIDATION_ENABLED == 1)
424     CORE_LOG_D("CORE3D_VALIDATION: creating camera color targets %s", customCamRngId.data());
425 #endif
426     // This (re-)creates all the needed color targets
427     GpuImageDesc desc = cameraResourceSetup.inputImageDescs.color;
428     desc.width = targetDesc.width;
429     desc.height = targetDesc.height;
430     desc.layerCount = targetDesc.layerCount;
431     desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
432     if (camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) {
433         const bool directBackbufferResolve =
434             camera.renderPipelineType == RenderCamera::RenderPipelineType::LIGHT_FORWARD;
435 
436         GpuImageDesc msaaDesc = desc;
437         if (directBackbufferResolve) {
438             msaaDesc.format = targetDesc.format;
439         }
440         msaaDesc.engineCreationFlags |= CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS;
441         msaaDesc.sampleCountFlags = camera.msaaSampleCountFlags;
442         msaaDesc.usageFlags = CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
443         msaaDesc.memoryPropertyFlags =
444             CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
445 
446 #if (CORE3D_VALIDATION_ENABLED == 1)
447         createdTargets.colorMsaa = gpuResourceMgr.Create(
448             us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "MSAA_" + customCamRngId, msaaDesc);
449 #else
450         createdTargets.colorMsaa = gpuResourceMgr.Create(createdTargets.colorMsaa, msaaDesc);
451 #endif
452     }
453 
454     if (camera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD) {
455 #if (CORE3D_VALIDATION_ENABLED == 1)
456         createdTargets.colorResolve = gpuResourceMgr.Create(
457             us + DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + "RESL_" + customCamRngId, desc);
458 #else
459         createdTargets.colorResolve = gpuResourceMgr.Create(createdTargets.colorResolve, desc);
460 #endif
461     }
462 
463     CreateVelocityTarget(gpuResourceMgr, camera, targetDesc, us, customCamRngId, cameraResourceSetup, createdTargets);
464     CreateDeferredTargets(gpuResourceMgr, camera, targetDesc, us, customCamRngId, cameraResourceSetup, createdTargets);
465 
466     CreateHistoryTargets(gpuResourceMgr, camera, targetDesc, us, customCamRngId, cameraResourceSetup, createdTargets);
467 }
468 
CreateDepthTargets(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderCamera & camera,const GpuImageDesc & targetDesc,const string_view us,const string_view customCamRngId,RenderNodeDefaultCameraController::CameraResourceSetup & cameraResourceSetup,RenderNodeDefaultCameraController::CreatedTargets & createdTargets)469 void CreateDepthTargets(IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderCamera& camera,
470     const GpuImageDesc& targetDesc, const string_view us, const string_view customCamRngId,
471     RenderNodeDefaultCameraController::CameraResourceSetup& cameraResourceSetup,
472     RenderNodeDefaultCameraController::CreatedTargets& createdTargets)
473 {
474 #if (CORE3D_VALIDATION_ENABLED == 1)
475     CORE_LOG_D("CORE3D_VALIDATION: creating camera depth targets %s", customCamRngId.data());
476 #endif
477     // this (re-)creates all the needed depth targets
478     // we support cameras without depth targets (default depth is created if no msaa)
479     GpuImageDesc desc = cameraResourceSetup.inputImageDescs.depth;
480     desc.layerCount = targetDesc.layerCount;
481     desc.width = targetDesc.width;
482     desc.height = targetDesc.height;
483     desc.imageViewType = GetImageViewType(desc.layerCount, desc.imageViewType);
484     if (camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) {
485         GpuImageDesc msaaDesc = desc;
486         msaaDesc.engineCreationFlags |= CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS;
487         msaaDesc.sampleCountFlags = camera.msaaSampleCountFlags;
488         // If MSAA targets have input attachment bit they are not created as renderbuffers and
489         // EXT_multisample_render_to_texture supports only depth with renderbuffers.
490         msaaDesc.usageFlags = CORE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
491         msaaDesc.memoryPropertyFlags =
492             CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
493 #if (CORE3D_VALIDATION_ENABLED == 1)
494         createdTargets.depthMsaa = gpuResourceMgr.Create(
495             us + DefaultMaterialCameraConstants::CAMERA_DEPTH_PREFIX_NAME + "MSAA_" + customCamRngId, msaaDesc);
496 #else
497         createdTargets.depthMsaa = gpuResourceMgr.Create(createdTargets.depthMsaa, msaaDesc);
498 #endif
499     }
500     const bool createBasicDepth = (((camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) == 0) ||
501                                       ((camera.flags & RenderCamera::CAMERA_FLAG_OUTPUT_DEPTH_BIT) != 0)) &&
502                                   (!RenderHandleUtil::IsValid(camera.depthTarget.GetHandle()));
503     if (createBasicDepth) {
504         if (camera.flags & RenderCamera::CAMERA_FLAG_OUTPUT_DEPTH_BIT) {
505             desc.usageFlags |= CORE_IMAGE_USAGE_SAMPLED_BIT;
506             // we cannot have transient and lazy allocation
507             desc.usageFlags &= (~CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT);
508             desc.memoryPropertyFlags &= (~CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT);
509         }
510         createdTargets.depth =
511             gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_DEPTH_PREFIX_NAME + customCamRngId, desc);
512     }
513 
514     // store
515     createdTargets.imageDescs.depth = desc;
516 }
517 
ColorTargetsRecreationNeeded(const RenderCamera & camera,const RenderNodeDefaultCameraController::CameraResourceSetup & camRes,const GpuImageDesc & desc)518 bool ColorTargetsRecreationNeeded(const RenderCamera& camera,
519     const RenderNodeDefaultCameraController::CameraResourceSetup& camRes, const GpuImageDesc& desc)
520 {
521     constexpr RenderCamera::Flags importantFlags { RenderCamera::CAMERA_FLAG_HISTORY_BIT |
522                                                    RenderCamera::CAMERA_FLAG_OUTPUT_DEPTH_BIT |
523                                                    RenderCamera::CAMERA_FLAG_OUTPUT_VELOCITY_NORMAL_BIT };
524     const RenderCamera::Flags newFlags = camera.flags & importantFlags;
525     const RenderCamera::Flags oldFlags = camRes.camFlags & importantFlags;
526     const bool creationFlagsChanged = newFlags != oldFlags;
527     const bool pipelineChanged = (camera.renderPipelineType != camRes.pipelineType);
528     const bool resChanged = ((desc.width != camRes.outResolution.x) || (desc.height != camRes.outResolution.y));
529     // NOTE: currently compares only the output not the color i.e. the intermediate
530     const bool formatChanged = (!RenderHandleUtil::IsValid(camRes.colorTarget))
531                                    ? (desc.format != camRes.inputImageDescs.output.format)
532                                    : false;
533     const bool multiviewChanged = (camera.multiViewCameraCount > 0U) != camRes.isMultiview;
534     const bool msaaCountChanged =
535         (camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) && (camera.msaaSampleCountFlags != camRes.sampleCountFlags);
536 
537     bool changed = false;
538     if (creationFlagsChanged || pipelineChanged || resChanged || formatChanged || multiviewChanged ||
539         msaaCountChanged) {
540         changed = true;
541     }
542     return changed;
543 }
544 
DepthTargetsRecreationNeeded(const RenderCamera & camera,const RenderNodeDefaultCameraController::CameraResourceSetup & camRes,const GpuImageDesc & desc)545 bool DepthTargetsRecreationNeeded(const RenderCamera& camera,
546     const RenderNodeDefaultCameraController::CameraResourceSetup& camRes, const GpuImageDesc& desc)
547 {
548     constexpr RenderCamera::Flags importantFlags { RenderCamera::CAMERA_FLAG_OUTPUT_DEPTH_BIT };
549     const bool formatChanged =
550         (!RenderHandleUtil::IsValid(camRes.depthTarget)) ? (desc.format != camRes.inputImageDescs.depth.format) : false;
551     const bool resChanged = ((desc.width != camRes.outResolution.x) || (desc.height != camRes.outResolution.y));
552     const RenderCamera::Flags newFlags = camera.flags & importantFlags;
553     const RenderCamera::Flags oldFlags = camRes.camFlags & importantFlags;
554     const bool creationFlagsChanged = newFlags != oldFlags;
555     const bool multiviewChanged = (camera.multiViewCameraCount > 0U) != camRes.isMultiview;
556     const bool msaaCountChanged =
557         (camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) && (camera.msaaSampleCountFlags != camRes.sampleCountFlags);
558 
559     bool changed = false;
560     if (formatChanged || resChanged || creationFlagsChanged || multiviewChanged || msaaCountChanged) {
561         changed = true;
562     }
563     return changed;
564 }
565 } // namespace
566 
InitNode(IRenderNodeContextManager & renderNodeContextMgr)567 void RenderNodeDefaultCameraController::InitNode(IRenderNodeContextManager& renderNodeContextMgr)
568 {
569     renderNodeContextMgr_ = &renderNodeContextMgr;
570 
571     // get flags for rt
572     if constexpr (ENABLE_RT) {
573         rtEnabled_ = false;
574         IRenderContext &renderContext = renderNodeContextMgr_->GetRenderContext();
575         CORE_NS::IClassRegister *cr = renderContext.GetInterface<CORE_NS::IClassRegister>();
576         if (cr != nullptr) {
577             IGraphicsContext *graphicsContext = CORE_NS::GetInstance<IGraphicsContext>(*cr, UID_GRAPHICS_CONTEXT);
578             if (graphicsContext) {
579                 const IGraphicsContext::CreateInfo ci = graphicsContext->GetCreateInfo();
580                 if (ci.createFlags & IGraphicsContext::CreateInfo::ENABLE_ACCELERATION_STRUCTURES_BIT) {
581                     rtEnabled_ = true;
582                 }
583             }
584         } else {
585             CORE_LOG_E("get null ClassRegister");
586         }
587     }
588 
589     SetDefaultGpuImageDescs();
590     ParseRenderNodeInputs();
591 
592     globalDescs_ = {};
593     if constexpr (RenderLightHelper::ENABLE_CLUSTERED_LIGHTING) {
594         // load the light clustering shader
595         if (renderNodeContextMgr_) {
596             auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
597 
598             clusterBinders_ = {};
599             clusterBinders_.shaderHandleCluster =
600                 shaderMgr.GetShaderHandle("3dshaders://computeshader/core3d_cluster_lights.shader");
601             clusterBinders_.pipelineLayout = shaderMgr.GetReflectionPipelineLayout(clusterBinders_.shaderHandleCluster);
602 
603             clusterBinders_.pl = shaderMgr.GetPipelineLayout(
604                 shaderMgr.GetPipelineLayoutHandle("3dpipelinelayouts://core3d_cluster_lights.shaderpl"));
605 
606             auto& psoMgr = renderNodeContextMgr.GetPsoManager();
607             clusterBinders_.psoHandle =
608                 psoMgr.GetComputePsoHandle(clusterBinders_.shaderHandleCluster, clusterBinders_.pipelineLayout, {});
609         }
610     }
611 
612     const auto& renderNodeGraphData = renderNodeContextMgr_->GetRenderNodeGraphData();
613     stores_ = RenderNodeSceneUtil::GetSceneRenderDataStores(
614         renderNodeContextMgr, renderNodeGraphData.renderNodeGraphDataStoreName);
615     dsWeatherName_ = RenderNodeSceneUtil::GetSceneRenderDataStore(stores_, RenderDataStoreWeather::TYPE_NAME);
616 
617     currentScene_ = {};
618     currentScene_.customCamRngName = jsonInputs_.customCameraName;
619 
620     // id checked first for custom camera
621     if (jsonInputs_.customCameraId != INVALID_CAM_ID) {
622         currentScene_.customCameraId = jsonInputs_.customCameraId;
623     } else if (!jsonInputs_.customCameraName.empty()) {
624         currentScene_.customCameraName = jsonInputs_.customCameraName;
625     }
626 
627     camRes_.backendType = renderNodeContextMgr_->GetRenderNodeGraphData().renderingConfiguration.renderBackend;
628     defaultCubemap_ = renderNodeContextMgr_->GetGpuResourceManager().GetImageHandle(
629         DefaultMaterialGpuResourceConstants::CORE_DEFAULT_SKYBOX_CUBEMAP);
630 
631     auto& gpuResourceMgr = renderNodeContextMgr.GetGpuResourceManager();
632     defaultSamplers_.cubemapHandle =
633         gpuResourceMgr.GetSamplerHandle(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_RADIANCE_CUBEMAP_SAMPLER);
634     defaultSamplers_.linearHandle = gpuResourceMgr.GetSamplerHandle("CORE_DEFAULT_SAMPLER_LINEAR_CLAMP");
635     defaultSamplers_.nearestHandle = gpuResourceMgr.GetSamplerHandle("CORE_DEFAULT_SAMPLER_NEAREST_CLAMP");
636     defaultSamplers_.linearMipHandle = gpuResourceMgr.GetSamplerHandle("CORE_DEFAULT_SAMPLER_LINEAR_MIPMAP_CLAMP");
637     defaultColorPrePassHandle_ = gpuResourceMgr.GetImageHandle("CORE_DEFAULT_GPU_IMAGE");
638 
639     const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
640     const auto* dataStoreScene =
641         static_cast<IRenderDataStoreDefaultScene*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
642     const auto* dataStoreCamera =
643         static_cast<IRenderDataStoreDefaultCamera*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
644     const auto* dataStoreLight =
645         static_cast<IRenderDataStoreDefaultLight*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameLight));
646 
647     if (dataStoreScene && dataStoreCamera && dataStoreLight) {
648         UpdateCurrentScene(*dataStoreScene, *dataStoreCamera, *dataStoreLight);
649         CreateResources();
650         RegisterOutputs();
651         CreateBuffers();
652 
653         // get the camera buffers
654         uboHandles_.cameraData = renderNodeContextMgr_->GetGpuResourceManager().GetBufferHandle(
655             dataStoreScene->GetName() + DefaultMaterialCameraConstants::CAMERA_DATA_BUFFER_NAME);
656         if (rtEnabled_) {
657             uboHandles_.tlas = renderNodeContextMgr_->GetGpuResourceManager().GetBufferHandle(
658                 dataStoreScene->GetName() + DefaultMaterialMaterialConstants::MATERIAL_TLAS_PREFIX_NAME);
659         }
660     }
661     shadowBuffers_ = GetShadowBufferNodeData(gpuResourceMgr, stores_.dataStoreNameScene);
662 }
663 
PreExecuteFrame()664 void RenderNodeDefaultCameraController::PreExecuteFrame()
665 {
666     const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
667     const auto* dataStoreScene =
668         static_cast<IRenderDataStoreDefaultScene*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
669     const auto* dataStoreCamera =
670         static_cast<IRenderDataStoreDefaultCamera*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
671     const auto* dataStoreLight =
672         static_cast<IRenderDataStoreDefaultLight*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameLight));
673 
674     if (dataStoreScene && dataStoreCamera && dataStoreLight) {
675         UpdateCurrentScene(*dataStoreScene, *dataStoreCamera, *dataStoreLight);
676         CreateResources();
677         RegisterOutputs();
678     }
679 
680     if constexpr (RenderLightHelper::ENABLE_CLUSTERED_LIGHTING) {
681         if (!clusterBinders_.clusterBuffersSet0) {
682             auto& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
683 
684             const DescriptorCounts dc =
685                 renderNodeContextMgr_->GetRenderNodeUtil().GetDescriptorCounts(clusterBinders_.pl);
686             descriptorSetMgr.ResetAndReserve(dc);
687 
688             const RenderHandle setDescHandle = descriptorSetMgr.CreateDescriptorSet(0u, clusterBinders_.pl);
689             clusterBinders_.clusterBuffersSet0 = descriptorSetMgr.CreateDescriptorSetBinder(
690                 setDescHandle, clusterBinders_.pl.descriptorSetLayouts[0u].bindings);
691         }
692     }
693     if (!globalDescs_.dmSet0Binder) {
694         auto& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
695         const IRenderNodeShaderManager& shaderMgr = renderNodeContextMgr_->GetShaderManager();
696         const IShaderManager::RenderSlotData shaderRsd = shaderMgr.GetRenderSlotData(
697             shaderMgr.GetRenderSlotId(DefaultMaterialShaderConstants::RENDER_SLOT_FORWARD_OPAQUE));
698         const PipelineLayout pl = shaderMgr.GetPipelineLayout(shaderRsd.pipelineLayout.GetHandle());
699 
700         const string_view us = stores_.dataStoreNameScene;
701         string camName;
702         if (currentScene_.customCameraId != INVALID_CAM_ID) {
703             camName = to_string(currentScene_.customCameraId);
704         } else if (!(currentScene_.customCameraName.empty())) {
705             camName = currentScene_.customCameraName;
706         }
707         globalDescs_ = {};
708         const auto& bindings = pl.descriptorSetLayouts[0U].bindings;
709         globalDescs_.dmSet0 = descriptorSetMgr.CreateGlobalDescriptorSet(
710             us + DefaultMaterialMaterialConstants::MATERIAL_SET0_GLOBAL_DESCRIPTOR_SET_PREFIX_NAME + camName, bindings);
711         globalDescs_.dmSet0Binder =
712             descriptorSetMgr.CreateDescriptorSetBinder(globalDescs_.dmSet0.GetHandle(), bindings);
713     }
714 }
715 
ExecuteFrame(IRenderCommandList & cmdList)716 void RenderNodeDefaultCameraController::ExecuteFrame(IRenderCommandList& cmdList)
717 {
718     UpdateBuffers();
719     UpdateGlobalDescriptorSets(cmdList);
720     if constexpr (RenderLightHelper::ENABLE_CLUSTERED_LIGHTING) {
721         ClusterLights(cmdList);
722     }
723 }
724 
UpdateGlobalDescriptorSets(IRenderCommandList & cmdList)725 void RenderNodeDefaultCameraController::UpdateGlobalDescriptorSets(IRenderCommandList& cmdList)
726 {
727     if (!globalDescs_.dmSet0Binder) {
728         return;
729     }
730 
731     auto& binder = *globalDescs_.dmSet0Binder;
732     {
733         uint32_t bindingIndex = 0;
734         binder.BindBuffer(bindingIndex++, uboHandles_.cameraData, 0u);
735         binder.BindBuffer(bindingIndex++, uboHandles_.generalData.GetHandle(), 0u);
736 
737         const RenderHandle radianceCubemap = currentScene_.cameraEnvRadianceHandle;
738         const RenderHandle colorPrePass = RenderHandleUtil::IsValid(currentScene_.prePassColorTarget)
739                                               ? currentScene_.prePassColorTarget
740                                               : defaultColorPrePassHandle_;
741 
742         binder.BindBuffer(
743             bindingIndex++, { uboHandles_.environment.GetHandle(), 0u, PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE });
744         binder.BindBuffer(
745             bindingIndex++, { uboHandles_.fog.GetHandle(), 0u, PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE });
746         binder.BindBuffer(
747             bindingIndex++, { uboHandles_.light.GetHandle(), 0u, PipelineStateConstants ::GPU_BUFFER_WHOLE_SIZE });
748         binder.BindBuffer(
749             bindingIndex++, { uboHandles_.postProcess.GetHandle(), 0u, PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE });
750         binder.BindBuffer(bindingIndex++,
751             { uboHandles_.lightCluster.GetHandle(), 0u, PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE });
752         // use immutable samplers for all set 0 samplers
753         AdditionalDescriptorFlags descFlags = 0U;
754         if constexpr (USE_IMMUTABLE_SAMPLERS) {
755             descFlags = CORE_ADDITIONAL_DESCRIPTOR_IMMUTABLE_SAMPLER_BIT;
756         }
757         BindableImage bi;
758         bi.handle = colorPrePass;
759         bi.samplerHandle = defaultSamplers_.linearMipHandle;
760         binder.BindImage(bindingIndex++, bi, descFlags);
761         bi.handle = shadowBuffers_.vsmColorHandle;
762         bi.samplerHandle = shadowBuffers_.vsmSamplerHandle;
763         binder.BindImage(bindingIndex++, bi, descFlags);
764         bi.handle = shadowBuffers_.depthHandle;
765         bi.samplerHandle = shadowBuffers_.pcfSamplerHandle;
766         binder.BindImage(bindingIndex++, bi, descFlags);
767         bi.handle = radianceCubemap;
768         bi.samplerHandle = defaultSamplers_.cubemapHandle;
769         binder.BindImage(bindingIndex++, bi, descFlags);
770 
771         // bind acceleration structure
772         if (rtEnabled_) {
773             binder.BindBuffer(bindingIndex++, uboHandles_.tlas, 0U);
774         }
775     }
776 
777     const RenderHandle handles[] { binder.GetDescriptorSetHandle() };
778     const DescriptorSetLayoutBindingResources resources[] { binder.GetDescriptorSetLayoutBindingResources() };
779     cmdList.UpdateDescriptorSets(handles, resources);
780 }
781 
UpdateCurrentScene(const IRenderDataStoreDefaultScene & dataStoreScene,const IRenderDataStoreDefaultCamera & dataStoreCamera,const IRenderDataStoreDefaultLight & dataStoreLight)782 void RenderNodeDefaultCameraController::UpdateCurrentScene(const IRenderDataStoreDefaultScene& dataStoreScene,
783     const IRenderDataStoreDefaultCamera& dataStoreCamera, const IRenderDataStoreDefaultLight& dataStoreLight)
784 {
785     const auto scene = dataStoreScene.GetScene();
786     uint32_t cameraIdx = scene.cameraIndex;
787     if (currentScene_.customCameraId != INVALID_CAM_ID) {
788         cameraIdx = dataStoreCamera.GetCameraIndex(currentScene_.customCameraId);
789     } else if (!(currentScene_.customCameraName.empty())) {
790         cameraIdx = dataStoreCamera.GetCameraIndex(currentScene_.customCameraName);
791     }
792 
793     if (const auto cameras = dataStoreCamera.GetCameras(); cameraIdx < (uint32_t)cameras.size()) {
794         // store current frame camera
795         currentScene_.camera = cameras[cameraIdx];
796     }
797 
798     const auto camHandles = RenderNodeSceneUtil::GetSceneCameraImageHandles(
799         *renderNodeContextMgr_, stores_.dataStoreNameScene, currentScene_.camera.name, currentScene_.camera);
800     currentScene_.cameraEnvRadianceHandle = camHandles.radianceCubemap;
801 
802     if (!currentScene_.camera.prePassColorTargetName.empty()) {
803         currentScene_.prePassColorTarget =
804             renderNodeContextMgr_->GetGpuResourceManager().GetImageHandle(currentScene_.camera.prePassColorTargetName);
805     }
806 
807     currentScene_.cameraIdx = cameraIdx;
808     currentScene_.sceneTimingData = { scene.sceneDeltaTime, scene.deltaTime, scene.totalTime,
809         *reinterpret_cast<const float*>(&scene.frameIndex) };
810 
811     ValidateRenderCamera(currentScene_.camera);
812 
813     UpdatePostProcessConfiguration();
814 }
815 
RegisterOutputs()816 void RenderNodeDefaultCameraController::RegisterOutputs()
817 {
818     if ((currentScene_.customCameraId == INVALID_CAM_ID) && currentScene_.customCameraName.empty()) {
819         return;
820     }
821 
822     const CreatedTargetHandles cth = FillCreatedTargets(createdTargets_);
823     const RenderHandle colorTarget = RenderHandleUtil::IsValid(camRes_.colorTarget) ? camRes_.colorTarget : cth.color;
824     const RenderHandle depthTarget = RenderHandleUtil::IsValid(camRes_.depthTarget) ? camRes_.depthTarget : cth.depth;
825 
826     IRenderNodeGraphShareManager& shrMgr = renderNodeContextMgr_->GetRenderNodeGraphShareManager();
827     shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_OUTPUT, colorTarget);
828     shrMgr.RegisterGlobalRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_OUTPUT, colorTarget);
829 
830     // color is output always, depth usually (not with MSAA if not forced)
831     // colorResolve is used with msaa and hdr, the output is the 32 bit srgb color usually
832     const RenderHandle regDepth = RenderHandleUtil::IsValid(cth.depth) ? cth.depth : depthTarget;
833     const RenderHandle regColor = RenderHandleUtil::IsValid(cth.colorResolve) ? cth.colorResolve : colorTarget;
834     if (RenderHandleUtil::IsValid(regDepth)) {
835         shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH, regDepth);
836         shrMgr.RegisterGlobalRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH, regDepth);
837     }
838     shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR, regColor);
839     shrMgr.RegisterGlobalRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR, regColor);
840     if (RenderHandleUtil::IsValid(cth.velNor)) {
841         shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_VELOCITY_NORMAL, cth.velNor);
842         shrMgr.RegisterGlobalRenderNodeOutput(
843             DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_VELOCITY_NORMAL, cth.velNor);
844     }
845     // NOTE: HDR does not have float intermediate target ATM
846     if (currentScene_.camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) {
847         shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_BASE_COLOR, cth.baseColor);
848         shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_MATERIAL, cth.material);
849         shrMgr.RegisterGlobalRenderNodeOutput(
850             DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_BASE_COLOR, cth.baseColor);
851         shrMgr.RegisterGlobalRenderNodeOutput(
852             DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_MATERIAL, cth.material);
853     } else if (currentScene_.camera.flags & (RenderCamera::CAMERA_FLAG_MSAA_BIT)) {
854         shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH_MSAA, cth.depthMsaa);
855         shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR_MSAA, cth.colorMsaa);
856         shrMgr.RegisterGlobalRenderNodeOutput(
857             DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH_MSAA, cth.depthMsaa);
858         shrMgr.RegisterGlobalRenderNodeOutput(
859             DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR_MSAA, cth.colorMsaa);
860     }
861 
862     // output history
863     if (currentScene_.camera.flags & RenderCamera::CameraFlagBits::CAMERA_FLAG_HISTORY_BIT) {
864         const uint32_t currIndex = camRes_.historyFlipFrame;
865         const uint32_t nextIndex = (currIndex + 1u) % 2u;
866         shrMgr.RegisterRenderNodeOutput(
867             DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY, createdTargets_.history[currIndex].GetHandle());
868         shrMgr.RegisterRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY_NEXT,
869             createdTargets_.history[nextIndex].GetHandle());
870         shrMgr.RegisterGlobalRenderNodeOutput(
871             DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY, createdTargets_.history[currIndex].GetHandle());
872         shrMgr.RegisterGlobalRenderNodeOutput(DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY_NEXT,
873             createdTargets_.history[nextIndex].GetHandle());
874         camRes_.historyFlipFrame = nextIndex;
875     }
876 }
877 
CreateResources()878 void RenderNodeDefaultCameraController::CreateResources()
879 {
880     if ((currentScene_.customCameraId == INVALID_CAM_ID) && currentScene_.customCameraName.empty()) {
881         return;
882     }
883 
884     // NOTE: with CAMERA_FLAG_MAIN_BIT we support rendering to cameras without targets
885     // if no depth is given, we create a transient depth
886     CreateResourceBaseTargets();
887 
888     IRenderNodeGpuResourceManager& gpuResMgr = renderNodeContextMgr_->GetGpuResourceManager();
889     const auto& camera = currentScene_.camera;
890     bool validDepthHandle = RenderHandleUtil::IsValid(camRes_.depthTarget);
891     const bool isHdr = (camera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD);
892     const bool isMsaa = (camera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT);
893     const bool isDeferred = (camera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED);
894     const bool isMultiview = (camera.multiViewCameraCount > 0U);
895     const uint32_t mvLayerCount = isMultiview ? (camera.multiViewCameraCount + 1U) : 1U;
896     if (validDepthHandle && isMultiview) {
897         validDepthHandle = false;
898 #if (CORE3D_VALIDATION_ENABLED == 1)
899         CORE_LOG_ONCE_W(renderNodeContextMgr_->GetName() + "cam_controller_multiview_depth",
900             "CORE3D_VALIDATION: Multi-view not supported with custom depth targets (creating new layered depth)");
901 #endif
902     }
903     if ((!validDepthHandle) || isMsaa || isHdr || isDeferred) {
904         GpuImageDesc colorDesc = RenderHandleUtil::IsValid(camRes_.colorTarget)
905                                      ? gpuResMgr.GetImageDescriptor(camRes_.colorTarget)
906                                      : gpuResMgr.GetImageDescriptor(createdTargets_.outputColor.GetHandle());
907 
908         if (isMultiview) {
909             colorDesc.layerCount = mvLayerCount;
910         }
911         const bool colorTargetChanged = ColorTargetsRecreationNeeded(camera, camRes_, colorDesc);
912 
913         GpuImageDesc depthDesc;
914         if (!validDepthHandle) {
915             depthDesc = colorDesc;
916             depthDesc.format = createdTargets_.imageDescs.depth.format;
917         } else {
918             depthDesc = gpuResMgr.GetImageDescriptor(camRes_.depthTarget);
919         }
920         bool depthTargetChanged = DepthTargetsRecreationNeeded(camera, camRes_, depthDesc);
921         // depth size needs to match color
922         if ((colorDesc.width != depthDesc.width) || (colorDesc.height != depthDesc.height)) {
923             depthTargetChanged = true;
924             depthDesc.width = colorDesc.width;
925             depthDesc.height = colorDesc.height;
926         }
927 
928         camRes_.outResolution.x = colorDesc.width;
929         camRes_.outResolution.y = colorDesc.height;
930         camRes_.renResolution = currentScene_.camera.renderResolution;
931         camRes_.camFlags = camera.flags;
932         camRes_.pipelineType = camera.renderPipelineType;
933         camRes_.isMultiview = (camera.multiViewCameraCount > 0U);
934         camRes_.sampleCountFlags = camera.msaaSampleCountFlags;
935         if (isMultiview) {
936             colorDesc.layerCount = mvLayerCount;
937         }
938 
939         if ((camRes_.renResolution.x < 1U) || (camRes_.renResolution.y < 1U)) {
940             camRes_.renResolution.x = Math::max(1u, colorDesc.width);
941             camRes_.renResolution.y = Math::max(1u, colorDesc.height);
942 #if (CORE3D_VALIDATION_ENABLED == 1)
943             const string_view nodeName = renderNodeContextMgr_->GetName();
944             CORE_LOG_ONCE_E(nodeName + "cam_controller_renRes",
945                 "CORE3D_VALIDATION: RN:%s camera render resolution resized to match target %ux%u", nodeName.data(),
946                 camRes_.renResolution.x, camRes_.renResolution.y);
947 #endif
948         }
949 
950         const bool enableRenderRes = (camera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD);
951         if (enableRenderRes) {
952             colorDesc.width = camRes_.renResolution.x;
953             colorDesc.height = camRes_.renResolution.y;
954             depthDesc.width = camRes_.renResolution.x;
955             depthDesc.height = camRes_.renResolution.y;
956         }
957 
958         // all decisions are done based on color and depth targets
959         const string_view us = stores_.dataStoreNameScene;
960         if (colorTargetChanged) {
961             CreateColorTargets(
962                 gpuResMgr, camera, colorDesc, us, currentScene_.customCamRngName, camRes_, createdTargets_);
963         }
964         if (depthTargetChanged) {
965             CreateDepthTargets(
966                 gpuResMgr, camera, depthDesc, us, currentScene_.customCamRngName, camRes_, createdTargets_);
967         }
968     }
969 }
970 
CreateResourceBaseTargets()971 void RenderNodeDefaultCameraController::CreateResourceBaseTargets()
972 {
973     IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
974     const auto& camera = currentScene_.camera;
975 
976     camRes_.colorTarget = camera.colorTargets[0].GetHandle();
977     camRes_.depthTarget = camera.depthTarget.GetHandle();
978     // update formats if given
979     auto UpdateTargetFormats = [](const auto& input, auto& output) {
980         if (input.format != BASE_FORMAT_UNDEFINED) {
981             output.format = input.format;
982         }
983         if (input.usageFlags != 0) {
984             output.usageFlags = input.usageFlags;
985         }
986     };
987     UpdateTargetFormats(camera.colorTargetCustomization[0U], camRes_.inputImageDescs.output);
988     UpdateTargetFormats(camera.colorTargetCustomization[0U], camRes_.inputImageDescs.color);
989     UpdateTargetFormats(camera.depthTargetCustomization, camRes_.inputImageDescs.depth);
990     if (camera.flags & RenderCamera::CAMERA_FLAG_MAIN_BIT) {
991 #if (CORE3D_VALIDATION_ENABLED == 1)
992         if ((!RenderHandleUtil::IsValid(camRes_.colorTarget)) &&
993             (camera.flags & RenderCamera::CAMERA_FLAG_CUBEMAP_BIT)) {
994             CORE_LOG_ONCE_W(renderNodeContextMgr_->GetName() + "cubemap_def_backbuffer",
995                 "CORE3D_VALIDATION: camera (%s) main camera with default backbuffer cannot be cubemap camera",
996                 currentScene_.customCamRngName.data());
997         }
998 #endif
999         if ((!RenderHandleUtil::IsValid(camRes_.colorTarget)) &&
1000             ((camera.flags & RenderCamera::CAMERA_FLAG_CUBEMAP_BIT) == 0)) {
1001             camRes_.colorTarget = gpuResourceMgr.GetImageHandle("CORE_DEFAULT_BACKBUFFER");
1002 #if (CORE3D_VALIDATION_ENABLED == 1)
1003             CORE_LOG_ONCE_I(renderNodeContextMgr_->GetName() + "using_def_backbuffer",
1004                 "CORE3D_VALIDATION: camera (%s) using CORE_DEFAULT_BACKBUFFER", currentScene_.customCamRngName.data());
1005 #endif
1006         }
1007     }
1008     if (!RenderHandleUtil::IsValid(camRes_.colorTarget)) {
1009         const string_view us = stores_.dataStoreNameScene;
1010         if (createdTargets_.outputColor) {
1011             const GpuImageDesc colorDesc = gpuResourceMgr.GetImageDescriptor(createdTargets_.outputColor.GetHandle());
1012             if ((colorDesc.width != camera.renderResolution.x) || (colorDesc.height != camera.renderResolution.y)) {
1013                 CreateBaseColorTarget(
1014                     gpuResourceMgr, camera, us, currentScene_.customCamRngName, camRes_, createdTargets_);
1015             }
1016         } else {
1017             CreateBaseColorTarget(gpuResourceMgr, camera, us, currentScene_.customCamRngName, camRes_, createdTargets_);
1018         }
1019     }
1020 }
1021 
CreateBuffers()1022 void RenderNodeDefaultCameraController::CreateBuffers()
1023 {
1024     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1025     string camName;
1026     if (currentScene_.customCameraId != INVALID_CAM_ID) {
1027         camName = to_string(currentScene_.customCameraId);
1028     } else if (!(currentScene_.customCameraName.empty())) {
1029         camName = currentScene_.customCameraName;
1030     }
1031     constexpr MemoryPropertyFlags memPropertyFlags =
1032         (CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT | CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT);
1033     const string_view us = stores_.dataStoreNameScene;
1034     uboHandles_.generalData =
1035         gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_GENERAL_BUFFER_PREFIX_NAME + camName,
1036             GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
1037                 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER,
1038                 static_cast<uint32_t>(sizeof(DefaultMaterialGeneralDataStruct)) });
1039     uboHandles_.environment =
1040         gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_ENVIRONMENT_BUFFER_PREFIX_NAME + camName,
1041             GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
1042                 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER,
1043                 static_cast<uint32_t>(sizeof(DefaultMaterialEnvironmentStruct)) *
1044                     CORE_DEFAULT_MATERIAL_MAX_ENVIRONMENT_COUNT });
1045     uboHandles_.fog = gpuResourceMgr.Create(
1046         us + DefaultMaterialCameraConstants::CAMERA_FOG_BUFFER_PREFIX_NAME + camName,
1047         GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
1048             CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, static_cast<uint32_t>(sizeof(DefaultMaterialFogStruct)) });
1049     uboHandles_.postProcess = gpuResourceMgr.Create(
1050         us + DefaultMaterialCameraConstants::CAMERA_POST_PROCESS_BUFFER_PREFIX_NAME + camName,
1051         GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
1052             CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, static_cast<uint32_t>(sizeof(GlobalPostProcessStruct)) });
1053 
1054     uboHandles_.light =
1055         gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_LIGHT_BUFFER_PREFIX_NAME + camName,
1056             GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memPropertyFlags,
1057                 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, sizeof(DefaultMaterialLightStruct) });
1058 
1059     // NOTE: storage buffer
1060     uboHandles_.lightCluster =
1061         gpuResourceMgr.Create(us + DefaultMaterialCameraConstants::CAMERA_LIGHT_CLUSTER_BUFFER_PREFIX_NAME + camName,
1062             GpuBufferDesc { CORE_BUFFER_USAGE_STORAGE_BUFFER_BIT, memPropertyFlags,
1063                 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER,
1064                 sizeof(DefaultMaterialLightClusterData) * CORE_DEFAULT_MATERIAL_MAX_CLUSTERS_COUNT });
1065 }
1066 
UpdateBuffers()1067 void RenderNodeDefaultCameraController::UpdateBuffers()
1068 {
1069     UpdateGeneralUniformBuffer();
1070     UpdateLightBuffer();
1071     UpdateEnvironmentUniformBuffer();
1072     UpdateFogUniformBuffer();
1073     UpdatePostProcessUniformBuffer();
1074 }
1075 
UpdateGeneralUniformBuffer()1076 void RenderNodeDefaultCameraController::UpdateGeneralUniformBuffer()
1077 {
1078     const auto& camera = currentScene_.camera;
1079     const Math::Vec2 viewportSize = { static_cast<float>(camera.renderResolution.x),
1080         static_cast<float>(camera.renderResolution.y) };
1081     DefaultMaterialGeneralDataStruct dataStruct {
1082         { currentScene_.cameraIdx, 0u, 0u, 0u },
1083         { viewportSize.x, viewportSize.y, 1.0f / viewportSize.x, 1.0f / viewportSize.y },
1084         currentScene_.sceneTimingData,
1085     };
1086 
1087     IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1088     if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.generalData.GetHandle())); data) {
1089         const auto* dataEnd = data + sizeof(DefaultMaterialGeneralDataStruct);
1090         if (!CloneData(data, size_t(dataEnd - data), &dataStruct, sizeof(DefaultMaterialGeneralDataStruct))) {
1091             CORE_LOG_E("generalData ubo copying failed.");
1092         }
1093         gpuResourceMgr.UnmapBuffer(uboHandles_.generalData.GetHandle());
1094     }
1095 }
1096 
UpdatePostProcessUniformBuffer()1097 void RenderNodeDefaultCameraController::UpdatePostProcessUniformBuffer()
1098 {
1099     CORE_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == sizeof(RenderPostProcessConfiguration));
1100     IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1101     if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.postProcess.GetHandle())); data) {
1102         const auto* dataEnd = data + sizeof(GlobalPostProcessStruct);
1103         if (!CloneData(data, size_t(dataEnd - data), &currentRenderPPConfiguration_, sizeof(GlobalPostProcessStruct))) {
1104             CORE_LOG_E("post process ubo copying failed.");
1105         }
1106         gpuResourceMgr.UnmapBuffer(uboHandles_.postProcess.GetHandle());
1107     }
1108 }
1109 
1110 namespace {
GetMultiEnvironmentIndices(const RenderCamera & cam)1111 Math::UVec4 GetMultiEnvironmentIndices(const RenderCamera& cam)
1112 {
1113     if (cam.environment.multiEnvCount > 0U) {
1114         Math::UVec4 multiEnvIndices = { 0U, 0U, 0U, 0U };
1115         // the first value in multiEnvIndices is the count
1116         // first index is the main environment, next indices are the blend environments
1117         for (uint32_t idx = 1U; idx < cam.environment.multiEnvCount; ++idx) {
1118             multiEnvIndices[0U]++;
1119             multiEnvIndices[idx] = idx;
1120         }
1121         return multiEnvIndices;
1122     } else {
1123         return { 0U, 0U, 0U, 0U };
1124     }
1125 }
1126 
GetWeatherSettings(const IRenderNodeRenderDataStoreManager & rdsMgr,const string_view dsName)1127 inline RenderDataStoreWeather::WeatherSettings GetWeatherSettings(
1128     const IRenderNodeRenderDataStoreManager& rdsMgr, const string_view dsName)
1129 {
1130     if (const auto* dsWeather = static_cast<RenderDataStoreWeather*>(rdsMgr.GetRenderDataStore(dsName)); dsWeather) {
1131         return dsWeather->GetWeatherSettings();
1132     } else {
1133         return {};
1134     }
1135 }
1136 
1137 } // namespace
1138 
UpdateEnvironmentUniformBuffer()1139 void RenderNodeDefaultCameraController::UpdateEnvironmentUniformBuffer()
1140 {
1141     BASE_NS::Math::Vec4
1142         defaultSHIndirectCoefficients[9u] {}; // nine vectors which are used in spherical harmonics calculations
1143     defaultSHIndirectCoefficients[0] = { 1.0f, 1.0f, 1.0f, 1.0f };
1144     constexpr uint32_t envByteSize =
1145         sizeof(DefaultMaterialEnvironmentStruct) * CORE_DEFAULT_MATERIAL_MAX_ENVIRONMENT_COUNT;
1146 
1147     const auto& rdsMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
1148     if (const auto* dsCamera =
1149             static_cast<IRenderDataStoreDefaultCamera*>(rdsMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
1150         dsCamera) {
1151         const RenderDataStoreWeather::WeatherSettings ws = GetWeatherSettings(rdsMgr, dsWeatherName_);
1152 
1153         // the environments needs to be in camera sorted order
1154         // we fetch environments one by one based on their id
1155         // in typical scenario there's only one environment present and others are filled with default data
1156         IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1157         if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.environment.GetHandle()));
1158             data) {
1159             const auto* dataEnd = data + envByteSize;
1160             const auto& camera = currentScene_.camera;
1161             const Math::UVec4 multiEnvIndices = GetMultiEnvironmentIndices(camera);
1162             // process main environment and multi envs
1163             const uint32_t envCount = 1U + camera.environment.multiEnvCount;
1164             for (uint32_t idx = 0; idx < envCount; ++idx) {
1165                 const RenderCamera::Environment currEnv =
1166                     (idx == 0U) ? camera.environment
1167                                 : dsCamera->GetEnvironment(camera.environment.multiEnvIds[idx - 1U]);
1168 
1169                 const Math::UVec2 id = GetPacked64(currEnv.id);
1170                 const Math::UVec2 layer = GetPacked64(currEnv.layerMask);
1171                 const float radianceCubemapLodCoeff =
1172                     (currEnv.radianceCubemapMipCount != 0)
1173                         ? Math::min(CUBE_MAP_LOD_COEFF, static_cast<float>(currEnv.radianceCubemapMipCount))
1174                         : CUBE_MAP_LOD_COEFF;
1175                 DefaultMaterialEnvironmentStruct envStruct {
1176                     Math::Vec4((Math::Vec3(currEnv.indirectSpecularFactor) * currEnv.indirectSpecularFactor.w),
1177                         currEnv.indirectSpecularFactor.w),
1178                     Math::Vec4(Math::Vec3(currEnv.indirectDiffuseFactor) * currEnv.indirectDiffuseFactor.w,
1179                         currEnv.indirectDiffuseFactor.w),
1180                     Math::Vec4(Math::Vec3(currEnv.envMapFactor) * currEnv.envMapFactor.w, currEnv.envMapFactor.w),
1181                     Math::Vec4(radianceCubemapLodCoeff, currEnv.envMapLodLevel, 0.0f, 0.0f),
1182                     currEnv.blendFactor,
1183                     Math::Mat4Cast(currEnv.rotation),
1184                     Math::UVec4(id.x, id.y, layer.x, layer.y),
1185                     {},
1186                     multiEnvIndices,
1187                     {},
1188                     {},
1189                 };
1190                 constexpr size_t countOfSh = countof(envStruct.shIndirectCoefficients);
1191                 if (currEnv.radianceCubemap || (currEnv.multiEnvCount > 0U)) {
1192                     for (size_t jdx = 0; jdx < countOfSh; ++jdx) {
1193                         envStruct.shIndirectCoefficients[jdx] = currEnv.shIndirectCoefficients[jdx];
1194                     }
1195                 } else {
1196                     for (size_t jdx = 0; jdx < countOfSh; ++jdx) {
1197                         envStruct.shIndirectCoefficients[jdx] = defaultSHIndirectCoefficients[jdx];
1198                     }
1199                 }
1200                 // sky atmosphere
1201                 envStruct.packedSun = Math::Vec4(ws.sunPos, 0.0f);
1202                 envStruct.packedRain = { ws.coverage, ws.precipitation, ws.cloudType, 0.0f };
1203 
1204                 if (!CloneData(data, size_t(dataEnd - data), &envStruct, sizeof(DefaultMaterialEnvironmentStruct))) {
1205                     CORE_LOG_E("environment ubo copying failed.");
1206                 }
1207                 data = data + sizeof(DefaultMaterialEnvironmentStruct);
1208             }
1209             gpuResourceMgr.UnmapBuffer(uboHandles_.environment.GetHandle());
1210         }
1211     }
1212 }
1213 
UpdateFogUniformBuffer()1214 void RenderNodeDefaultCameraController::UpdateFogUniformBuffer()
1215 {
1216     const auto& camera = currentScene_.camera;
1217     const RenderCamera::Fog& fog = camera.fog;
1218     const Math::UVec2 id = GetPacked64(fog.id);
1219     const Math::UVec2 layer = GetPacked64(fog.layerMask);
1220     const DefaultMaterialFogStruct fogStruct {
1221         Math::UVec4 { id.x, id.y, layer.x, layer.y },
1222         fog.firstLayer,
1223         fog.secondLayer,
1224         fog.baseFactors,
1225         fog.inscatteringColor,
1226         fog.envMapFactor,
1227         fog.additionalFactor,
1228     };
1229     IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1230     if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.fog.GetHandle())); data) {
1231         const auto* dataEnd = data + sizeof(DefaultMaterialFogStruct);
1232         if (!CloneData(data, size_t(dataEnd - data), &fogStruct, sizeof(DefaultMaterialFogStruct))) {
1233             CORE_LOG_E("fog ubo copying failed.");
1234         }
1235         gpuResourceMgr.UnmapBuffer(uboHandles_.fog.GetHandle());
1236     }
1237 }
1238 
UpdateLightBuffer()1239 void RenderNodeDefaultCameraController::UpdateLightBuffer()
1240 {
1241     const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
1242     const auto* dataStoreScene =
1243         static_cast<IRenderDataStoreDefaultScene*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
1244     const auto* dataStoreLight =
1245         static_cast<IRenderDataStoreDefaultLight*>(renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameLight));
1246 
1247     // NOTE: should be culled by camera view frustum (or clustering can handle that)
1248     if (dataStoreScene && dataStoreLight) {
1249         auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1250         const auto scene = dataStoreScene->GetScene();
1251         const uint32_t sceneId = currentScene_.camera.sceneId;
1252         const auto& lights = dataStoreLight->GetLights();
1253         const Math::Vec4 shadowAtlasSizeInvSize = RenderLightHelper::GetShadowAtlasSizeInvSize(*dataStoreLight);
1254         const uint32_t shadowCount = dataStoreLight->GetLightCounts().shadowCount;
1255         // light buffer update (needs to be updated every frame)
1256         if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(uboHandles_.light.GetHandle())); data) {
1257             // NOTE: do not read data from mapped buffer (i.e. do not use mapped buffer as input to anything)
1258             RenderLightHelper::LightCounts lightCounts;
1259             const uint32_t lightCount = std::min(CORE_DEFAULT_MATERIAL_MAX_LIGHT_COUNT, (uint32_t)lights.size());
1260             vector<RenderLightHelper::SortData> sortedFlags =
1261                 RenderLightHelper::SortLights(lights, lightCount, sceneId);
1262 
1263             auto* singleLightStruct =
1264                 reinterpret_cast<DefaultMaterialSingleLightStruct*>(data + RenderLightHelper::LIGHT_LIST_OFFSET);
1265             for (size_t idx = 0; idx < sortedFlags.size(); ++idx) {
1266                 const auto& sortData = sortedFlags[idx];
1267                 const auto& light = lights[sortData.index];
1268                 if (light.layerMask & currentScene_.camera.layerMask) {
1269                     // drop lights with no matching camera layers
1270                     using UsageFlagBits = RenderLight::LightUsageFlagBits;
1271                     if (sortData.lightUsageFlags & UsageFlagBits::LIGHT_USAGE_DIRECTIONAL_LIGHT_BIT) {
1272                         lightCounts.directionalLightCount++;
1273                     } else if (sortData.lightUsageFlags & UsageFlagBits::LIGHT_USAGE_POINT_LIGHT_BIT) {
1274                         lightCounts.pointLightCount++;
1275                     } else if (sortData.lightUsageFlags & UsageFlagBits::LIGHT_USAGE_SPOT_LIGHT_BIT) {
1276                         lightCounts.spotLightCount++;
1277                     }
1278 
1279                     RenderLightHelper::CopySingleLight(lights[sortData.index], shadowCount, singleLightStruct++);
1280                 }
1281             }
1282 
1283             DefaultMaterialLightStruct* lightStruct = reinterpret_cast<DefaultMaterialLightStruct*>(data);
1284             lightStruct->directionalLightBeginIndex = 0;
1285             lightStruct->directionalLightCount = lightCounts.directionalLightCount;
1286             lightStruct->pointLightBeginIndex = lightCounts.directionalLightCount;
1287             lightStruct->pointLightCount = lightCounts.pointLightCount;
1288             lightStruct->spotLightBeginIndex = lightCounts.directionalLightCount + lightCounts.pointLightCount;
1289             lightStruct->spotLightCount = lightCounts.spotLightCount;
1290             lightStruct->pad0 = 0;
1291             lightStruct->pad1 = 0;
1292             lightStruct->clusterSizes = Math::UVec4(0, 0, 0, 0);
1293             lightStruct->clusterFactors = Math::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
1294             lightStruct->atlasSizeInvSize = shadowAtlasSizeInvSize;
1295             lightStruct->additionalFactors = { 0.0f, 0.0f, 0.0f, 0.0f };
1296 
1297             gpuResourceMgr.UnmapBuffer(uboHandles_.light.GetHandle());
1298         }
1299     }
1300 }
1301 
UpdatePostProcessConfiguration()1302 void RenderNodeDefaultCameraController::UpdatePostProcessConfiguration()
1303 {
1304     const auto& dataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
1305     if (auto* dataStore = static_cast<IRenderDataStorePod*>(dataStoreMgr.GetRenderDataStore(POD_DATA_STORE_NAME));
1306         dataStore) {
1307         auto const dataView = dataStore->Get(currentScene_.camera.postProcessName);
1308         if (dataView.data() && (dataView.size_bytes() == sizeof(PostProcessConfiguration))) {
1309             const PostProcessConfiguration* data = (const PostProcessConfiguration*)dataView.data();
1310             currentRenderPPConfiguration_ =
1311                 renderNodeContextMgr_->GetRenderNodeUtil().GetRenderPostProcessConfiguration(*data);
1312         }
1313     }
1314 }
1315 
ClusterLights(RENDER_NS::IRenderCommandList & cmdList)1316 void RenderNodeDefaultCameraController::ClusterLights(RENDER_NS::IRenderCommandList& cmdList)
1317 {
1318     cmdList.BindPipeline(clusterBinders_.psoHandle);
1319 
1320     {
1321         auto& binder = *clusterBinders_.clusterBuffersSet0;
1322 
1323         uint32_t binding = 0;
1324         binder.BindBuffer(binding++, uboHandles_.cameraData, 0);
1325         binder.BindBuffer(binding++, uboHandles_.generalData.GetHandle(), 0);
1326         binder.BindBuffer(binding++, uboHandles_.light.GetHandle(), 0);
1327         binder.BindBuffer(binding++, uboHandles_.lightCluster.GetHandle(), 0);
1328 
1329         if (!binder.GetDescriptorSetLayoutBindingValidity()) {
1330             return;
1331         }
1332 
1333         cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources());
1334         cmdList.BindDescriptorSet(0, binder.GetDescriptorSetHandle());
1335     }
1336 
1337     const uint32_t tgx = (CORE_DEFAULT_MATERIAL_MAX_CLUSTERS_COUNT + (LIGHT_CLUSTER_TGS - 1)) / LIGHT_CLUSTER_TGS;
1338     cmdList.Dispatch(tgx, 1, 1);
1339 
1340     {
1341         // add barrier for memory
1342         constexpr GeneralBarrier src { AccessFlagBits::CORE_ACCESS_SHADER_WRITE_BIT,
1343             PipelineStageFlagBits::CORE_PIPELINE_STAGE_COMPUTE_SHADER_BIT };
1344         constexpr GeneralBarrier dst { AccessFlagBits::CORE_ACCESS_INDIRECT_COMMAND_READ_BIT |
1345                                            AccessFlagBits::CORE_ACCESS_SHADER_WRITE_BIT,
1346             PipelineStageFlagBits::CORE_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
1347                 PipelineStageFlagBits::CORE_PIPELINE_STAGE_COMPUTE_SHADER_BIT };
1348 
1349         cmdList.CustomMemoryBarrier(src, dst);
1350         cmdList.AddCustomBarrierPoint();
1351     }
1352 }
1353 
SetDefaultGpuImageDescs()1354 void RenderNodeDefaultCameraController::SetDefaultGpuImageDescs()
1355 {
1356     camRes_.inputImageDescs.depth = DEPTH_DEFAULT_DESC;
1357 
1358     camRes_.inputImageDescs.output = OUTPUT_DEFAULT_DESC;
1359     camRes_.inputImageDescs.color = COLOR_DEFAULT_DESC;
1360     camRes_.inputImageDescs.velocityNormal = VELOCITY_NORMAL_DEFAULT_DESC;
1361     camRes_.inputImageDescs.history = HISTORY_DEFAULT_DESC;
1362     camRes_.inputImageDescs.baseColor = BASE_COLOR_DEFAULT_DESC;
1363     camRes_.inputImageDescs.material = MATERIAL_DEFAULT_DESC;
1364 }
1365 
ParseRenderNodeInputs()1366 void RenderNodeDefaultCameraController::ParseRenderNodeInputs()
1367 {
1368     const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil();
1369     const auto jsonVal = renderNodeContextMgr_->GetNodeJson();
1370     jsonInputs_.customCameraName = parserUtil.GetStringValue(jsonVal, "customCameraName");
1371     jsonInputs_.customCameraId = parserUtil.GetUintValue(jsonVal, "customCameraId");
1372 
1373     const vector<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> imageDescs =
1374         parserUtil.GetGpuImageDescs(jsonVal, "gpuImageDescs");
1375 
1376     for (const auto& ref : imageDescs) {
1377         if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_OUTPUT) {
1378             camRes_.inputImageDescs.output = ref.desc;
1379         } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH) {
1380             camRes_.inputImageDescs.depth = ref.desc;
1381         } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR) {
1382             camRes_.inputImageDescs.color = ref.desc;
1383         } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY) {
1384             camRes_.inputImageDescs.history = ref.desc;
1385         } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_VELOCITY_NORMAL) {
1386             camRes_.inputImageDescs.velocityNormal = ref.desc;
1387         } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_BASE_COLOR) {
1388             camRes_.inputImageDescs.baseColor = ref.desc;
1389         } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_MATERIAL) {
1390             camRes_.inputImageDescs.material = ref.desc;
1391         }
1392     }
1393 
1394     // validate
1395     const IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
1396     ValidateDepthDesc(gpuResourceMgr, DEPTH_DEFAULT_DESC, camRes_.inputImageDescs.depth);
1397     ValidateColorDesc(gpuResourceMgr, OUTPUT_DEFAULT_DESC, true, camRes_.inputImageDescs.output);
1398     ValidateColorDesc(gpuResourceMgr, COLOR_DEFAULT_DESC, true, camRes_.inputImageDescs.color);
1399     ValidateColorDesc(gpuResourceMgr, VELOCITY_NORMAL_DEFAULT_DESC, true, camRes_.inputImageDescs.velocityNormal);
1400     ValidateColorDesc(gpuResourceMgr, HISTORY_DEFAULT_DESC, true, camRes_.inputImageDescs.history);
1401     ValidateColorDesc(gpuResourceMgr, BASE_COLOR_DEFAULT_DESC, false, camRes_.inputImageDescs.baseColor);
1402     ValidateColorDesc(gpuResourceMgr, MATERIAL_DEFAULT_DESC, false, camRes_.inputImageDescs.material);
1403 }
1404 
1405 // for plugin / factory interface
Create()1406 RENDER_NS::IRenderNode* RenderNodeDefaultCameraController::Create()
1407 {
1408     return new RenderNodeDefaultCameraController();
1409 }
1410 
Destroy(IRenderNode * instance)1411 void RenderNodeDefaultCameraController::Destroy(IRenderNode* instance)
1412 {
1413     delete static_cast<RenderNodeDefaultCameraController*>(instance);
1414 }
1415 CORE3D_END_NAMESPACE()
1416