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