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