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