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