OverviewFilesCommitsIssuesDocsReleasesPeers

nvidia-rtx-godot commits / 0be596d

implement raytraced skinned mesh
0be596d67186867c6b23edbcf686a81f7e51c7e0
by maidopi-usagi <maidopi@qq.com> · 2026-05-07T06:57:55.000Z

Changed files (18) +424 -43

drivers/d3d12/rendering_device_driver_d3d12.cpp +4 -0
……@@ -5591,6 +5591,10 @@ void RenderingDeviceDriverD3D12::command_build_blas(CommandBufferID p_cmd_buffer
55915591 ERR_FAIL_MSG("Ray tracing is not currently supported by the D3D12 driver.");
55925592}
55935593
5594void RenderingDeviceDriverD3D12::command_update_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) {
5595 ERR_FAIL_MSG("Ray tracing is not currently supported by the D3D12 driver.");
5596}
5597
55945598void RenderingDeviceDriverD3D12::command_build_tlas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer, BufferID p_instance_buffer, uint32_t p_instance_offset, uint32_t p_instance_count) {
55955599 ERR_FAIL_MSG("Ray tracing is not currently supported by the D3D12 driver.");
55965600}
drivers/d3d12/rendering_device_driver_d3d12.h +1 -0
……@@ -855,6 +855,7 @@ public:
855855 // ----- COMMANDS -----
856856
857857 virtual void command_build_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) override final;
858 virtual void command_update_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) override final;
858859 virtual void command_build_tlas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer, BufferID p_instance_buffer, uint32_t p_instance_offset, uint32_t p_instance_count) override final;
859860 virtual void command_bind_raytracing_pipeline(CommandBufferID p_cmd_buffer, RaytracingPipelineID p_pipeline) override final;
860861 virtual void command_bind_raytracing_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
drivers/metal/rendering_device_driver_metal.cpp +4 -0
……@@ -2307,6 +2307,10 @@ void RenderingDeviceDriverMetal::command_build_blas(CommandBufferID p_cmd_buffer
23072307 ERR_FAIL_MSG("Ray tracing is not currently supported by the Metal driver.");
23082308}
23092309
2310void RenderingDeviceDriverMetal::command_update_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) {
2311 ERR_FAIL_MSG("Ray tracing is not currently supported by the Metal driver.");
2312}
2313
23102314void RenderingDeviceDriverMetal::command_build_tlas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer, BufferID p_instance_buffer, uint32_t p_instance_offset, uint32_t p_instance_count) {
23112315 ERR_FAIL_MSG("Ray tracing is not currently supported by the Metal driver.");
23122316}
drivers/metal/rendering_device_driver_metal.h +1 -0
……@@ -478,6 +478,7 @@ public:
478478 // ----- COMMANDS -----
479479
480480 virtual void command_build_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) override final;
481 virtual void command_update_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) override final;
481482 virtual void command_build_tlas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer, BufferID p_instance_buffer, uint32_t p_instance_offset, uint32_t p_instance_count) override final;
482483 virtual void command_bind_raytracing_pipeline(CommandBufferID p_cmd_buffer, RaytracingPipelineID p_pipeline) override final;
483484 virtual void command_bind_raytracing_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
drivers/vulkan/rendering_device_driver_vulkan.cpp +28 -1
……@@ -6527,7 +6527,13 @@ void RenderingDeviceDriverVulkan::_acceleration_structure_create(VkAccelerationS
65276527
65286528 // Scratch address must be a multiple of minAccelerationStructureScratchOffsetAlignment.
65296529 r_accel_info->scratch_alignment = acceleration_structure_capabilities.min_acceleration_structure_scratch_offset_alignment;
6530 r_accel_info->scratch_size = p_size_info.buildScratchSize + r_accel_info->scratch_alignment;
6530 // When ALLOW_UPDATE is requested, scratch must accommodate the larger of build/update sizes
6531 // because the same scratch buffer is reused for both code paths.
6532 VkDeviceSize required_scratch = p_size_info.buildScratchSize;
6533 if (r_accel_info->build_info.flags & VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR) {
6534 required_scratch = MAX(required_scratch, p_size_info.updateScratchSize);
6535 }
6536 r_accel_info->scratch_size = required_scratch + r_accel_info->scratch_alignment;
65316537
65326538 VkAccelerationStructureCreateInfoKHR accel_create_info = {};
65336539 accel_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
……@@ -6582,6 +6588,27 @@ void RenderingDeviceDriverVulkan::command_build_blas(CommandBufferID p_cmd_buffe
65826588 AccelerationStructureInfo *accel_info = (AccelerationStructureInfo *)p_acceleration_structure.id;
65836589
65846590 VkAccelerationStructureBuildGeometryInfoKHR *build_info = &accel_info->build_info;
6591 build_info->mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
6592 build_info->srcAccelerationStructure = VK_NULL_HANDLE;
6593 build_info->dstAccelerationStructure = accel_info->vk_acceleration_structure;
6594 VkDeviceAddress scratch_address = buffer_get_device_address(p_scratch_buffer);
6595 build_info->scratchData.deviceAddress = _align_up_address(scratch_address, accel_info->scratch_alignment);
6596
6597 const VkAccelerationStructureBuildRangeInfoKHR *range_infos = accel_info->range_infos.ptr();
6598
6599 vkCmdBuildAccelerationStructuresKHR(command_buffer->vk_command_buffer, 1, build_info, &range_infos);
6600#endif
6601}
6602
6603void RenderingDeviceDriverVulkan::command_update_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) {
6604#if VULKAN_RAYTRACING_ENABLED
6605 const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
6606 AccelerationStructureInfo *accel_info = (AccelerationStructureInfo *)p_acceleration_structure.id;
6607
6608 VkAccelerationStructureBuildGeometryInfoKHR *build_info = &accel_info->build_info;
6609 build_info->mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR;
6610 build_info->srcAccelerationStructure = accel_info->vk_acceleration_structure;
6611 build_info->dstAccelerationStructure = accel_info->vk_acceleration_structure;
65856612 VkDeviceAddress scratch_address = buffer_get_device_address(p_scratch_buffer);
65866613 build_info->scratchData.deviceAddress = _align_up_address(scratch_address, accel_info->scratch_alignment);
65876614
drivers/vulkan/rendering_device_driver_vulkan.h +1 -0
……@@ -735,6 +735,7 @@ private:
735735public:
736736 // ----- COMMANDS -----
737737 virtual void command_build_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) override final;
738 virtual void command_update_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) override final;
738739 virtual void command_build_tlas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer, BufferID p_instance_buffer, uint32_t p_instance_offset, uint32_t p_instance_count) override final;
739740 virtual void command_bind_raytracing_pipeline(CommandBufferID p_cmd_buffer, RaytracingPipelineID p_pipeline) override final;
740741 virtual void command_bind_raytracing_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
servers/rendering/renderer_rd/forward_clustered/render_raytracing.cpp +208 -37
……@@ -243,6 +243,18 @@ void RenderRaytracing::cleanup_caches() {
243243 }
244244 surface_chunks.clear();
245245
246 for (KeyValue<uint64_t, RTDeformedCacheEntry> &kv : deformed_surface_cache) {
247 RTDeformedCacheEntry &e = kv.value;
248 if (e.ptr) {
249 if (e.ptr->blas.is_valid()) {
250 RD::get_singleton()->free_rid(e.ptr->blas);
251 }
252 memdelete(e.ptr);
253 e.ptr = nullptr;
254 }
255 }
256 deformed_surface_cache.clear();
257
246258 // Free all cached material data
247259 for (uint32_t i = 0; i < material_chunks.size(); i++) {
248260 if (material_chunks[i]) {
……@@ -348,6 +360,27 @@ void RenderRaytracing::prepare_frame() {
348360 motion_transforms.clear();
349361
350362 // Procedural BLAS/AABB lifetime is on the geometry instance.
363 {
364 const uint32_t DEFORMED_CACHE_TTL_FRAMES = 60;
365 uint32_t current_frame = RSG::rasterizer->get_frame_number();
366 LocalVector<uint64_t> to_remove;
367 for (KeyValue<uint64_t, RTDeformedCacheEntry> &kv : deformed_surface_cache) {
368 RTDeformedCacheEntry &e = kv.value;
369 if (e.last_used_frame != 0 && current_frame - e.last_used_frame > DEFORMED_CACHE_TTL_FRAMES) {
370 if (e.ptr) {
371 if (e.ptr->blas.is_valid()) {
372 RD::get_singleton()->free_rid(e.ptr->blas);
373 }
374 memdelete(e.ptr);
375 e.ptr = nullptr;
376 }
377 to_remove.push_back(kv.key);
378 }
379 }
380 for (uint64_t k : to_remove) {
381 deformed_surface_cache.erase(k);
382 }
383 }
351384
352385 // Finish async HG compiles so live_ready_mask matches this frame (sync path fills at build_tlas end).
353386 SceneShaderRaytracing::get_singleton()->drain_completed_compiles();
……@@ -412,41 +445,152 @@ RTSurfaceData *RenderRaytracing::process_surface(
412445
413446 RTSurfaceData *surf_data = entry->ptr;
414447
415 // Get vertex/index arrays for BLAS creation
416 SceneShaderForwardClustered::ShaderData *shader_data = surf->shader;
417 bool emulate_point_size = shader_data->uses_point_size && owner->scene_shader.emulate_point_size;
448 _populate_surface_blas(p_mesh_surface, RID(), false, false, false, cache_key, surf_data, r_dirty_blas_list);
449
450 surf->cached_final_transform_valid = false;
451
452 if (!surf_data->blas.is_valid()) {
453 return surf_data;
454 }
455
456 entry->cached_counter = p_surface_invalidation_counter;
457 entry->cached_rid_version = mesh_version;
458 entry->last_used_frame = current_frame;
459
460 return surf_data;
461}
462
463// ---------------------------------------------------------------------------
464// Deformed surface processing
465// ---------------------------------------------------------------------------
466
467RTSurfaceData *RenderRaytracing::process_deformed_surface(
468 const void *p_surf,
469 void *p_mesh_surface,
470 const RTDeformedGeometrySource &p_source,
471 LocalVector<RID> &r_dirty_blas_list,
472 LocalVector<RID> &r_dirty_blas_update_list) {
473 const RenderForwardClustered::GeometryInstanceSurfaceDataCache *surf =
474 static_cast<const RenderForwardClustered::GeometryInstanceSurfaceDataCache *>(p_surf);
475
476 if (!p_source.current_vb.is_valid()) {
477 return nullptr;
478 }
479
480 uint32_t current_frame = RSG::rasterizer->get_frame_number();
481 uint64_t buffer_id = p_source.current_vb.get_id();
482
483 RTDeformedCacheEntry &entry = deformed_surface_cache[p_source.cache_key];
484
485 bool needs_refresh = !entry.ptr ||
486 entry.cached_key_version != p_source.cache_version ||
487 entry.cached_surface_counter != p_source.surface_counter ||
488 entry.cached_buffer_id != buffer_id ||
489 entry.cached_change_stamp != p_source.change_stamp;
490
491 auto stamp_deformed_geometry = [&](RTSurfaceData *p_surf_data) {
492 if (!p_surf_data || !p_surf_data->blas.is_valid()) {
493 return;
494 }
495 p_surf_data->geometry.flags |= RT_GEOM_FLAG_DEFORMED;
496 uint64_t prev_addr = 0;
497 if (p_source.prev_vb.is_valid() && p_source.prev_vb != p_source.current_vb) {
498 prev_addr = RD::get_singleton()->buffer_get_device_address(p_source.prev_vb);
499 }
500 p_surf_data->geometry.prev_vertex_buffer_address_lo = static_cast<uint32_t>(prev_addr & 0xFFFFFFFFULL);
501 p_surf_data->geometry.prev_vertex_buffer_address_hi = static_cast<uint32_t>(prev_addr >> 32);
502 };
503
504 if (!needs_refresh && entry.ptr->blas.is_valid()) {
505 cache_hits++;
506 entry.last_used_frame = current_frame;
507 stamp_deformed_geometry(entry.ptr);
508 return entry.ptr;
509 }
510
511 cache_misses++;
512
513 // Refit when only the current deformed vertex buffer contents changed.
514 bool can_refit = entry.ptr && entry.ptr->blas.is_valid() && entry.blas_built_once &&
515 entry.cached_key_version == p_source.cache_version &&
516 entry.cached_surface_counter == p_source.surface_counter &&
517 entry.cached_buffer_id == buffer_id;
518
519 if (can_refit) {
520 RTSurfaceData *surf_data = entry.ptr;
521 r_dirty_blas_update_list.push_back(surf_data->blas);
522 surf->cached_final_transform_valid = false;
523 stamp_deformed_geometry(surf_data);
524 entry.cached_change_stamp = p_source.change_stamp;
525 entry.last_used_frame = current_frame;
526 return surf_data;
527 }
528
529 if (!entry.ptr) {
530 entry.ptr = memnew(RTSurfaceData);
531 } else if (entry.ptr->blas.is_valid()) {
532 RD::get_singleton()->free_rid(entry.ptr->blas);
533 entry.ptr->blas = RID();
534 entry.blas_built_once = false;
535 }
536
537 RTSurfaceData *surf_data = entry.ptr;
538
539 _populate_surface_blas(p_mesh_surface, p_source.current_vb, true, true, true, static_cast<uint32_t>(p_source.cache_key), surf_data, r_dirty_blas_list);
540
541 surf->cached_final_transform_valid = false;
542
543 if (!surf_data->blas.is_valid()) {
544 return surf_data;
545 }
546
547 stamp_deformed_geometry(surf_data);
548
549 entry.blas_built_once = true;
550 entry.cached_change_stamp = p_source.change_stamp;
551 entry.cached_key_version = p_source.cache_version;
552 entry.cached_surface_counter = p_source.surface_counter;
553 entry.cached_buffer_id = buffer_id;
554 entry.last_used_frame = current_frame;
555
556 return surf_data;
557}
558
559// ---------------------------------------------------------------------------
560// Surface BLAS helper (shared between static and deformed paths)
561// ---------------------------------------------------------------------------
418562
419 SceneShaderForwardClustered::ShaderData::PipelineKey pipeline_key;
420 pipeline_key.primitive_type = surf->primitive;
421 pipeline_key.version = SceneShaderForwardClustered::PIPELINE_VERSION_COLOR_PASS;
422 pipeline_key.color_pass_flags = 0;
423 pipeline_key.wireframe = false;
424 pipeline_key.ubershader = 0;
563void RenderRaytracing::_populate_surface_blas(
564 void *p_mesh_surface,
565 RID p_vertex_buffer_override,
566 bool p_force_uncompressed,
567 bool p_prefer_fast_build,
568 bool p_allow_update,
569 uint32_t p_cache_key,
570 RTSurfaceData *r_surf_data,
571 LocalVector<RID> &r_dirty_blas_list) {
572 RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
425573
426 // Build geometry data
427574 uint64_t surface_format = mesh_storage->mesh_surface_get_format(p_mesh_surface);
428 bool compressed = surface_format & RSE::ARRAY_FLAG_COMPRESS_ATTRIBUTES;
575 bool compressed = (surface_format & RSE::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && !p_force_uncompressed;
429576 bool is_2d = surface_format & RSE::ARRAY_FLAG_USE_2D_VERTICES;
430577
431 surf_data->is_compressed = compressed;
578 r_surf_data->is_compressed = compressed;
432579
433 // Compute AABB transform for compressed meshes
434580 if (compressed) {
435581 AABB surface_aabb = mesh_storage->mesh_surface_get_aabb(p_mesh_surface);
436 surf_data->aabb_transform.basis = Basis::from_scale(surface_aabb.size);
437 surf_data->aabb_transform.origin = surface_aabb.position;
582 r_surf_data->aabb_transform.basis = Basis::from_scale(surface_aabb.size);
583 r_surf_data->aabb_transform.origin = surface_aabb.position;
438584 } else {
439 surf_data->aabb_transform = Transform3D();
585 r_surf_data->aabb_transform = Transform3D();
440586 }
441587
442 // Invalidate per-surface cached final transform since aabb_transform was recomputed.
443 surf->cached_final_transform_valid = false;
444
445 // Populate geometry data
446 RT_GeometryData &geom = surf_data->geometry;
588 RT_GeometryData &geom = r_surf_data->geometry;
447589 memset(&geom, 0, sizeof(geom));
448590
449 RID vertex_buffer = mesh_storage->mesh_surface_get_vertex_buffer(p_mesh_surface);
591 RID vertex_buffer = p_vertex_buffer_override.is_valid()
592 ? p_vertex_buffer_override
593 : mesh_storage->mesh_surface_get_vertex_buffer(p_mesh_surface);
450594 RID attribute_buffer = mesh_storage->mesh_surface_get_attribute_buffer(p_mesh_surface);
451595 RID index_buffer = mesh_storage->mesh_surface_get_index_buffer(p_mesh_surface, 0);
452596
……@@ -591,20 +735,21 @@ RTSurfaceData *RenderRaytracing::process_surface(
591735 as_geom.geometry.triangles.index_count = index_count;
592736 }
593737
594 surf_data->blas = RD::get_singleton()->blas_create({ &as_geom, 1 }, RD::ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT);
595 if (!surf_data->blas.is_valid()) {
596 return surf_data;
738 BitField<RD::AccelerationStructureFlagBits> as_flags = p_prefer_fast_build
739 ? RD::ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT
740 : RD::ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT;
741 if (p_allow_update) {
742 as_flags.set_flag(RD::ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT);
597743 }
598 RD::get_singleton()->set_resource_name(surf_data->blas, String("RT BLAS [") + itos(cache_key) + "]");
599 r_dirty_blas_list.push_back(surf_data->blas);
600 }
601
602 // Update cache entry
603 entry->cached_counter = p_surface_invalidation_counter;
604 entry->cached_rid_version = mesh_version;
605 entry->last_used_frame = current_frame;
606744
607 return surf_data;
745 r_surf_data->blas = RD::get_singleton()->blas_create({ &as_geom, 1 }, as_flags);
746 if (!r_surf_data->blas.is_valid()) {
747 return;
748 }
749 RD::get_singleton()->set_resource_name(r_surf_data->blas,
750 String(p_vertex_buffer_override.is_valid() ? "RT BLAS deformed [" : "RT BLAS [") + itos(p_cache_key) + "]");
751 r_dirty_blas_list.push_back(r_surf_data->blas);
752 }
608753}
609754
610755// ---------------------------------------------------------------------------
……@@ -1304,13 +1449,19 @@ RTMaterialData *RenderRaytracing::process_material(RID p_material_rid, uint16_t
13041449// Acceleration structure building
13051450// ---------------------------------------------------------------------------
13061451
1307void RenderRaytracing::build_acceleration_structures(RTViewportState *p_state, const LocalVector<RID> &p_dirty_blas_list) {
1452void RenderRaytracing::build_acceleration_structures(RTViewportState *p_state, const LocalVector<RID> &p_dirty_blas_list, const LocalVector<RID> &p_dirty_blas_update_list) {
13081453 for (const RID &blas_rid : p_dirty_blas_list) {
13091454 if (blas_rid.is_valid()) {
13101455 RD::get_singleton()->blas_build(blas_rid);
13111456 }
13121457 }
13131458
1459 for (const RID &blas_rid : p_dirty_blas_update_list) {
1460 if (blas_rid.is_valid()) {
1461 RD::get_singleton()->blas_update(blas_rid);
1462 }
1463 }
1464
13141465 uint32_t needed = MAX(blass.size(), (uint32_t)1);
13151466 if (!p_state->tlas.is_valid() || needed > p_state->tlas_max_instances) {
13161467 if (p_state->tlas.is_valid()) {
……@@ -1395,6 +1546,7 @@ RTViewportState *RenderRaytracing::build_tlas(const RenderDataRD *p_render_data,
13951546 RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
13961547 RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
13971548 LocalVector<RID> dirty_blas_list;
1549 LocalVector<RID> dirty_blas_update_list;
13981550
13991551#ifdef TOOLS_ENABLED
14001552 uint32_t tlas_instance_count = 0;
……@@ -1494,7 +1646,26 @@ RTViewportState *RenderRaytracing::build_tlas(const RenderDataRD *p_render_data,
14941646 void *mesh_surface = surf->surface;
14951647 uint32_t surface_counter = mesh_storage->mesh_surface_get_rt_invalidation_counter(mesh_surface);
14961648
1497 RTSurfaceData *surf_data = process_surface(surf, mesh_surface, surface_counter, instance_transform, dirty_blas_list);
1649 // MeshInstance skinning/blend shapes provide a deformed vertex buffer.
1650 RTSurfaceData *surf_data = nullptr;
1651 if (inst->mesh_instance.is_valid()) {
1652 RID curr_vb = mesh_storage->mesh_instance_get_vertex_buffer(inst->mesh_instance, surf->surface_index);
1653 if (curr_vb.is_valid()) {
1654 RTDeformedGeometrySource src;
1655 src.current_vb = curr_vb;
1656 src.prev_vb = mesh_storage->mesh_instance_get_prev_vertex_buffer(inst->mesh_instance, surf->surface_index);
1657 src.change_stamp = mesh_storage->mesh_instance_get_last_change(inst->mesh_instance, surf->surface_index);
1658 uint64_t mi_id = inst->mesh_instance.get_id();
1659 uint32_t mi_index = static_cast<uint32_t>(mi_id & 0xFFFFFFFFULL);
1660 src.cache_version = static_cast<uint32_t>(mi_id >> 32);
1661 src.cache_key = (static_cast<uint64_t>(mi_index) << 16) | (surf->surface_index & 0xFFFFu);
1662 src.surface_counter = surface_counter;
1663 surf_data = process_deformed_surface(surf, mesh_surface, src, dirty_blas_list, dirty_blas_update_list);
1664 }
1665 }
1666 if (!surf_data) {
1667 surf_data = process_surface(surf, mesh_surface, surface_counter, instance_transform, dirty_blas_list);
1668 }
14981669 if (!surf_data || !surf_data->blas.is_valid()) {
14991670 surf = surf->next;
15001671 continue;
……@@ -1612,7 +1783,7 @@ RTViewportState *RenderRaytracing::build_tlas(const RenderDataRD *p_render_data,
16121783
16131784 SceneShaderRaytracing::get_singleton()->finalize_custom_shaders();
16141785
1615 build_acceleration_structures(state, dirty_blas_list);
1786 build_acceleration_structures(state, dirty_blas_list, dirty_blas_update_list);
16161787 finalize_buffers(state);
16171788
16181789 return state;
servers/rendering/renderer_rd/forward_clustered/render_raytracing.h +44 -2
……@@ -79,7 +79,10 @@ struct alignas(16) RT_GeometryData {
7979 float aabb_pos_x;
8080 float aabb_pos_y;
8181 float aabb_pos_z;
82 uint32_t _pad[7];
82 // For deformed geometry: previous-frame position buffer used for motion vectors.
83 uint32_t prev_vertex_buffer_address_lo;
84 uint32_t prev_vertex_buffer_address_hi;
85 uint32_t _pad[5];
8386};
8487static_assert(sizeof(RT_GeometryData) == 128, "RT_GeometryData must be 128 bytes for std430");
8588
……@@ -166,6 +169,8 @@ enum {
166169enum {
167170 RT_GEOM_FLAG_COMPRESSED = 1u,
168171 RT_GEOM_FLAG_PROCEDURAL = 2u,
172 // Set when the BLAS uses a per-frame-deformed vertex buffer.
173 RT_GEOM_FLAG_DEFORMED = 4u,
169174};
170175
171176/// Per-instance state for procedural RT geometry. Heap-allocated, only exists for procedural instances.
……@@ -189,6 +194,16 @@ struct RTSurfaceData {
189194 uint64_t blas_size = 0;
190195};
191196
197/// Inputs for a surface backed by a per-frame-deformed vertex buffer.
198struct RTDeformedGeometrySource {
199 RID current_vb; ///< Vertex buffer (object-space positions) the BLAS is built / refit against.
200 RID prev_vb; ///< Previous-frame positions for motion vectors. Optional.
201 uint64_t change_stamp = 0; ///< Changes when `current_vb` contents change.
202 uint64_t cache_key = 0; ///< Caller-defined cache identity.
203 uint32_t cache_version = 0; ///< Changes when the resource behind `cache_key` is recycled.
204 uint32_t surface_counter = 0; ///< Changes when the underlying mesh surface changes.
205};
206
192207struct RTMaterialData {
193208 alignas(16) RT_MaterialData data = {};
194209 uint32_t global_buffer_index = UINT32_MAX;
……@@ -263,6 +278,18 @@ class RenderRaytracing {
263278 // Caching (chunked sparse caches indexed by RID low bits / 256).
264279 Vector<RTCacheEntry *> surface_chunks;
265280 Vector<RTMaterialCacheEntry *> material_chunks;
281
282 // BLAS cache for surfaces driven by per-frame-deformed vertex buffers.
283 struct RTDeformedCacheEntry {
284 RTSurfaceData *ptr = nullptr;
285 uint32_t last_used_frame = 0;
286 uint64_t cached_change_stamp = 0;
287 uint32_t cached_key_version = 0;
288 uint32_t cached_surface_counter = 0;
289 uint64_t cached_buffer_id = 0; // RID id of the deformed vertex buffer at the time of build.
290 bool blas_built_once = false; // True once the BLAS has been fully built; subsequent ticks can refit.
291 };
292 HashMap<uint64_t, RTDeformedCacheEntry> deformed_surface_cache;
266293 LocalVector<uint32_t> material_free_slots;
267294 uint32_t next_material_slot = 0;
268295 uint64_t vram_used = 0;
……@@ -315,9 +342,24 @@ class RenderRaytracing {
315342 uint32_t p_surface_invalidation_counter,
316343 const Transform3D &p_transform,
317344 LocalVector<RID> &r_dirty_blas_list);
345 RTSurfaceData *process_deformed_surface(
346 const void *p_surf,
347 void *p_mesh_surface,
348 const struct RTDeformedGeometrySource &p_source,
349 LocalVector<RID> &r_dirty_blas_list,
350 LocalVector<RID> &r_dirty_blas_update_list);
351 void _populate_surface_blas(
352 void *p_mesh_surface,
353 RID p_vertex_buffer_override,
354 bool p_force_uncompressed,
355 bool p_prefer_fast_build,
356 bool p_allow_update,
357 uint32_t p_cache_key,
358 RTSurfaceData *r_surf_data,
359 LocalVector<RID> &r_dirty_blas_list);
318360 RTMaterialData *process_material(RID p_material_rid, uint16_t p_material_invalidation_counter);
319361 void update_procedural_blas(RTProceduralState *p_state, LocalVector<RID> &r_dirty_blas_list);
320 void build_acceleration_structures(RTViewportState *p_state, const LocalVector<RID> &p_dirty_blas_list);
362 void build_acceleration_structures(RTViewportState *p_state, const LocalVector<RID> &p_dirty_blas_list, const LocalVector<RID> &p_dirty_blas_update_list);
321363 void finalize_buffers(RTViewportState *p_state);
322364 void prepare_frame();
323365
servers/rendering/renderer_rd/shaders/raytracing/raytracing_closest_hit_common_inc.glsl +25 -1
……@@ -166,13 +166,37 @@ void write_primary_hit_velocity(vec3 hit_pos) {
166166 vec3 obj_pos = (mat4(gl_WorldToObjectEXT) * vec4(hit_pos, 1.0)).xyz;
167167 vec3 prev_obj_pos = obj_pos;
168168
169#ifdef ENABLE_INTERSECTION_SHADERS
170169 GeometryData geom = geometries[geom_idx];
170
171#ifdef ENABLE_INTERSECTION_SHADERS
171172 if ((geom.flags & FLAG_PROCEDURAL) != 0u) {
172173 prev_obj_pos += decode_prev_pos_delta();
173174 }
174175#endif
175176
177#ifdef RT_HIT_ATTRIBS_DECLARED
178 if ((geom.flags & FLAG_DEFORMED) != 0u) {
179 uint64_t prev_addr = packUint2x32(uvec2(geom.prev_vertex_address_lo, geom.prev_vertex_address_hi));
180 if (prev_addr != 0ul) {
181 uint i0, i1, i2;
182 get_triangle_indices(geom, i0, i1, i2);
183 vec3 bary = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
184 FloatBuffer prev_vb = FloatBuffer(prev_addr);
185 uint stride_floats = geom.position_stride >> 2;
186 vec3 p0 = vec3(prev_vb.v[i0 * stride_floats + 0u],
187 prev_vb.v[i0 * stride_floats + 1u],
188 prev_vb.v[i0 * stride_floats + 2u]);
189 vec3 p1 = vec3(prev_vb.v[i1 * stride_floats + 0u],
190 prev_vb.v[i1 * stride_floats + 1u],
191 prev_vb.v[i1 * stride_floats + 2u]);
192 vec3 p2 = vec3(prev_vb.v[i2 * stride_floats + 0u],
193 prev_vb.v[i2 * stride_floats + 1u],
194 prev_vb.v[i2 * stride_floats + 2u]);
195 prev_obj_pos = bary.x * p0 + bary.y * p1 + bary.z * p2;
196 }
197 }
198#endif
199
176200 vec3 prev_world_pos = (prev_model * vec4(prev_obj_pos, 1.0)).xyz;
177201
178202 vec2 curr_uv = project_uv(hit_pos, curr_vp_unjittered);
servers/rendering/renderer_rd/shaders/raytracing/raytracing_data_inc.glsl +5 -1
……@@ -44,7 +44,11 @@ struct GeometryData {
4444 float aabb_pos_y;
4545 float aabb_pos_z;
4646
47 uint _pad[7];
47 // For deformed geometry: previous-frame position buffer used for motion vectors.
48 uint prev_vertex_address_lo;
49 uint prev_vertex_address_hi;
50
51 uint _pad[5];
4852};
4953
5054void get_aabb_compression_xforms(GeometryData geom, out mat4 aabb_xform, out mat4 inv_aabb_xform) {
servers/rendering/renderer_rd/shaders/raytracing/raytracing_inc.glsl +2 -0
……@@ -140,6 +140,8 @@ bool is_path_terminated(uint packed) {
140140const uint OFFSET_NONE = 0xFFFFFFFFu;
141141const uint FLAG_COMPRESSED = 1u;
142142const uint FLAG_PROCEDURAL = 2u;
143// Set when the BLAS uses a per-frame-deformed vertex buffer.
144const uint FLAG_DEFORMED = 4u;
143145
144146// ============================================================================
145147// RANDOM NUMBER GENERATION - PCG (Permuted Congruential Generator)
servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +7 -1
……@@ -1079,7 +1079,13 @@ void MeshStorage::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint3
10791079}
10801080
10811081void MeshStorage::_mesh_instance_add_surface_buffer(MeshInstance *mi, Mesh *mesh, MeshInstance::Surface *s, uint32_t p_surface, uint32_t p_buffer_index) {
1082 s->vertex_buffer[p_buffer_index] = RD::get_singleton()->vertex_buffer_create(mesh->surfaces[p_surface]->vertex_buffer_size, Vector<uint8_t>(), RD::BUFFER_CREATION_AS_STORAGE_BIT);
1082 BitField<RD::BufferCreationBits> buffer_flags = RD::BUFFER_CREATION_AS_STORAGE_BIT;
1083 // Allow this skinned/blend-shape output buffer to be consumed by the raytracing path as a BLAS triangle source.
1084 if (RD::get_singleton()->has_feature(RD::SUPPORTS_RAYTRACING_PIPELINE) || RD::get_singleton()->has_feature(RD::SUPPORTS_RAY_QUERY)) {
1085 buffer_flags.set_flag(RD::BUFFER_CREATION_DEVICE_ADDRESS_BIT);
1086 buffer_flags.set_flag(RD::BUFFER_CREATION_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT);
1087 }
1088 s->vertex_buffer[p_buffer_index] = RD::get_singleton()->vertex_buffer_create(mesh->surfaces[p_surface]->vertex_buffer_size, Vector<uint8_t>(), buffer_flags);
10831089
10841090 Vector<RD::Uniform> uniforms;
10851091 {
servers/rendering/renderer_rd/storage_rd/mesh_storage.h +33 -0
……@@ -485,6 +485,39 @@ public:
485485 return s->vertex_buffer;
486486 }
487487
488 /// Get the per-mesh-instance skinned/blend-shape vertex buffer for the current frame.
489 /// Returns RID() when this surface is not deformed (caller should fall back to mesh_surface_get_vertex_buffer).
490 _FORCE_INLINE_ RID mesh_instance_get_vertex_buffer(RID p_mesh_instance, uint32_t p_surface_index) {
491 MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
492 if (!mi || p_surface_index >= mi->surfaces.size()) {
493 return RID();
494 }
495 const MeshInstance::Surface &mis = mi->surfaces[p_surface_index];
496 return mis.vertex_buffer[mis.current_buffer];
497 }
498
499 /// Get the previous-frame skinned vertex buffer (for motion vector reconstruction).
500 /// Returns the current buffer when the surface was not updated this frame, or when
501 /// update_mesh_instances() did not double-buffer this surface.
502 _FORCE_INLINE_ RID mesh_instance_get_prev_vertex_buffer(RID p_mesh_instance, uint32_t p_surface_index) {
503 MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
504 if (!mi || p_surface_index >= mi->surfaces.size()) {
505 return RID();
506 }
507 const MeshInstance::Surface &mis = mi->surfaces[p_surface_index];
508 uint32_t previous_buffer = RSG::rasterizer->get_frame_number() == mis.last_change ? mis.previous_buffer : mis.current_buffer;
509 return mis.vertex_buffer[previous_buffer];
510 }
511
512 /// Frame number on which this mesh-instance surface was last skinned (0 if never deformed).
513 _FORCE_INLINE_ uint64_t mesh_instance_get_last_change(RID p_mesh_instance, uint32_t p_surface_index) {
514 MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
515 if (!mi || p_surface_index >= mi->surfaces.size()) {
516 return 0;
517 }
518 return mi->surfaces[p_surface_index].last_change;
519 }
520
488521 /// Get the attribute buffer RID for raytracing device address access.
489522 _FORCE_INLINE_ RID mesh_surface_get_attribute_buffer(void *p_surface) {
490523 Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
servers/rendering/rendering_device.cpp +21 -0
……@@ -514,6 +514,27 @@ Error RenderingDevice::blas_build(RID p_blas) {
514514 return OK;
515515}
516516
517Error RenderingDevice::blas_update(RID p_blas) {
518 ERR_RENDER_THREAD_GUARD_V(ERR_UNAVAILABLE);
519
520 ERR_FAIL_COND_V_MSG(draw_list.active, ERR_INVALID_PARAMETER, "Updating BLAS is forbidden during creation of a draw list.");
521 ERR_FAIL_COND_V_MSG(compute_list.active, ERR_INVALID_PARAMETER, "Updating BLAS is forbidden during creation of a compute list.");
522 ERR_FAIL_COND_V_MSG(raytracing_list.active, ERR_INVALID_PARAMETER, "Updating BLAS is forbidden during creation of a raytracing list.");
523
524 AccelerationStructure *blas = acceleration_structure_owner.get_or_null(p_blas);
525 ERR_FAIL_NULL_V_MSG(blas, ERR_INVALID_PARAMETER, "BLAS argument is not valid.");
526
527 Error err = _acceleration_structure_scratch_buffer_create(blas);
528 ERR_FAIL_COND_V(err != OK, err);
529
530 draw_graph.add_blas_update(blas->driver_id, blas->scratch_buffer, blas->draw_tracker, blas->draw_trackers);
531
532 blas->invalidated = false;
533 _blas_remove_tlas_dependencies(blas, p_blas);
534
535 return OK;
536}
537
517538Error RenderingDevice::tlas_build(RID p_tlas, Span<AccelerationStructureInstance> p_instances) {
518539 ERR_RENDER_THREAD_GUARD_V(ERR_UNAVAILABLE);
519540
servers/rendering/rendering_device.h +4 -0
……@@ -1417,6 +1417,10 @@ public:
14171417 };
14181418
14191419 Error blas_build(RID p_blas);
1420 // In-place refit of a BLAS that was created with ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT and
1421 // previously fully built; only vertex positions may have changed since then. Significantly
1422 // cheaper than blas_build for skinned/animated meshes.
1423 Error blas_update(RID p_blas);
14201424 Error tlas_build(RID p_tlas, Span<AccelerationStructureInstance> p_instances);
14211425
14221426private:
servers/rendering/rendering_device_driver.h +3 -0
……@@ -828,6 +828,9 @@ public:
828828 // ----- COMMANDS -----
829829
830830 virtual void command_build_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) = 0;
831 // In-place refit of a BLAS previously built with ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT.
832 // Geometry topology / counts must be unchanged; only vertex positions may differ.
833 virtual void command_update_blas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer) = 0;
831834 virtual void command_build_tlas(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure, BufferID p_scratch_buffer, BufferID p_instance_buffer, uint32_t p_instance_offset, uint32_t p_instance_count) = 0;
832835 virtual void command_bind_raytracing_pipeline(CommandBufferID p_cmd_buffer, RaytracingPipelineID p_pipeline) = 0;
833836 virtual void command_bind_raytracing_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) = 0;
servers/rendering/rendering_device_graph.cpp +31 -0
……@@ -1085,6 +1085,10 @@ void RenderingDeviceGraph::_run_render_commands(int32_t p_level, const RecordedC
10851085 const RecordedBottomLevelAccelerationStructureBuildCommand *blas_build_command = reinterpret_cast<const RecordedBottomLevelAccelerationStructureBuildCommand *>(command);
10861086 driver->command_build_blas(r_command_buffer, blas_build_command->acceleration_structure, blas_build_command->scratch_buffer);
10871087 } break;
1088 case RecordedCommand::TYPE_BOTTOM_LEVEL_ACCELERATION_STRUCTURE_UPDATE: {
1089 const RecordedBottomLevelAccelerationStructureBuildCommand *blas_update_command = reinterpret_cast<const RecordedBottomLevelAccelerationStructureBuildCommand *>(command);
1090 driver->command_update_blas(r_command_buffer, blas_update_command->acceleration_structure, blas_update_command->scratch_buffer);
1091 } break;
10881092 case RecordedCommand::TYPE_TOP_LEVEL_ACCELERATION_STRUCTURE_BUILD: {
10891093 const RecordedTopLevelAccelerationStructureBuildCommand *tlas_build_command = reinterpret_cast<const RecordedTopLevelAccelerationStructureBuildCommand *>(command);
10901094 driver->command_build_tlas(r_command_buffer, tlas_build_command->acceleration_structure, tlas_build_command->scratch_buffer, tlas_build_command->instance_buffer, tlas_build_command->instance_offset, tlas_build_command->instance_count);
……@@ -1810,6 +1814,32 @@ void RenderingDeviceGraph::add_blas_build(RDD::AccelerationStructureID p_acceler
18101814 _add_command_to_graph(trackers.ptr(), usages.ptr(), usages.size(), command_index, command);
18111815}
18121816
1817void RenderingDeviceGraph::add_blas_update(RDD::AccelerationStructureID p_acceleration_structure, RDD::BufferID p_scratch_buffer, ResourceTracker *p_dst_tracker, VectorView<ResourceTracker *> p_src_trackers) {
1818 int32_t command_index;
1819 RecordedBottomLevelAccelerationStructureBuildCommand *command = static_cast<RecordedBottomLevelAccelerationStructureBuildCommand *>(_allocate_command(sizeof(RecordedBottomLevelAccelerationStructureBuildCommand), command_index));
1820 command->type = RecordedCommand::TYPE_BOTTOM_LEVEL_ACCELERATION_STRUCTURE_UPDATE;
1821 command->self_stages = RDD::PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT;
1822 command->acceleration_structure = p_acceleration_structure;
1823 command->scratch_buffer = p_scratch_buffer;
1824
1825 thread_local LocalVector<ResourceTracker *> trackers;
1826 thread_local LocalVector<ResourceUsage> usages;
1827
1828 uint32_t resource_count = p_src_trackers.size() + 1;
1829 trackers.resize(resource_count);
1830 usages.resize(resource_count);
1831
1832 for (uint32_t i = 0; i < p_src_trackers.size(); ++i) {
1833 trackers[i] = p_src_trackers[i];
1834 usages[i] = RESOURCE_USAGE_STORAGE_BUFFER_READ;
1835 }
1836
1837 trackers[resource_count - 1] = p_dst_tracker;
1838 usages[resource_count - 1] = RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ_WRITE;
1839
1840 _add_command_to_graph(trackers.ptr(), usages.ptr(), usages.size(), command_index, command);
1841}
1842
18131843void RenderingDeviceGraph::add_tlas_build(RDD::AccelerationStructureID p_acceleration_structure, RDD::BufferID p_scratch_buffer, RDD::BufferID p_instance_buffer, uint32_t p_instance_offset, uint32_t p_instance_count, ResourceTracker *p_dst_tracker, VectorView<ResourceTracker *> p_src_trackers) {
18141844 int32_t command_index;
18151845 RecordedTopLevelAccelerationStructureBuildCommand *command = static_cast<RecordedTopLevelAccelerationStructureBuildCommand *>(_allocate_command(sizeof(RecordedTopLevelAccelerationStructureBuildCommand), command_index));
……@@ -2662,6 +2692,7 @@ void RenderingDeviceGraph::end(bool p_reorder_commands, bool p_full_barriers, RD
26622692 2, // TYPE_TEXTURE_UPDATE
26632693 2, // TYPE_CAPTURE_TIMESTAMP
26642694 5, // TYPE_DRIVER_CALLBACK
2695 6, // TYPE_BOTTOM_LEVEL_ACCELERATION_STRUCTURE_UPDATE
26652696 };
26662697 static_assert(std_size(PriorityTable) == RecordedCommand::TYPE_MAX, "PriorityTable must have one entry per RecordedCommand::Type");
26672698
servers/rendering/rendering_device_graph.h +2 -0
……@@ -120,6 +120,7 @@ public:
120120 TYPE_TEXTURE_UPDATE,
121121 TYPE_CAPTURE_TIMESTAMP,
122122 TYPE_DRIVER_CALLBACK,
123 TYPE_BOTTOM_LEVEL_ACCELERATION_STRUCTURE_UPDATE,
123124 TYPE_MAX
124125 };
125126
……@@ -891,6 +892,7 @@ public:
891892 void finalize();
892893 void begin();
893894 void add_blas_build(RDD::AccelerationStructureID p_blas, RDD::BufferID p_scratch_buffer, ResourceTracker *p_dst_tracker, VectorView<ResourceTracker *> p_src_trackers);
895 void add_blas_update(RDD::AccelerationStructureID p_blas, RDD::BufferID p_scratch_buffer, ResourceTracker *p_dst_tracker, VectorView<ResourceTracker *> p_src_trackers);
894896 void add_tlas_build(RDD::AccelerationStructureID p_tlas, RDD::BufferID p_scratch_buffer, RDD::BufferID p_instance_buffer, uint32_t p_instance_offset, uint32_t p_instance_count, ResourceTracker *p_dst_tracker, VectorView<ResourceTracker *> p_src_trackers);
895897 void add_buffer_clear(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_offset, uint32_t p_size);
896898 void add_buffer_copy(RDD::BufferID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, RDD::BufferCopyRegion p_region);