| 685 | } |
| 686 | |
| 687 | MeshAccelerationStructure::GPU MeshAccelerationStructure::ToGPU() |
| 688 | { |
| 689 | PROFILE_CPU(); |
| 690 | GPU gpu; |
| 691 | |
| 692 | // GPU BVH operates on a single mesh with 32-bit indices |
| 693 | MergeMeshes(true); |
| 694 | |
| 695 | // Construct BVH |
| 696 | const int32 BVH_STACK_SIZE = 32; // This must match HLSL shader |
| 697 | BuildBVH(0, BVH_STACK_SIZE); |
| 698 | |
| 699 | // Upload BVH |
| 700 | { |
| 701 | Array<GPUBVH> bvhData; |
| 702 | bvhData.Resize(_bvh.Count()); |
| 703 | for (int32 i = 0; i < _bvh.Count(); i++) |
| 704 | { |
| 705 | const auto& src = _bvh.Get()[i]; |
| 706 | auto& dst = bvhData.Get()[i]; |
| 707 | dst.BoundsMin = src.Bounds.Minimum; |
| 708 | dst.BoundsMax = src.Bounds.Maximum; |
| 709 | if (src.Leaf.IsLeaf) |
| 710 | { |
| 711 | dst.Index = src.Leaf.TriangleIndex * 3; |
| 712 | dst.Count = src.Leaf.TriangleCount * 3; |
| 713 | } |
| 714 | else |
| 715 | { |
| 716 | dst.Index = src.Node.ChildIndex; |
| 717 | dst.Count = -(int32)src.Node.ChildrenCount; // Mark as non-leaf |
| 718 | ASSERT(src.Node.ChildrenCount == 2); // GPU shader is hardcoded for 2 children per node |
| 719 | } |
| 720 | } |
| 721 | gpu.BVHBuffer = GPUBuffer::New(); |
| 722 | auto desc =GPUBufferDescription::Structured(_bvh.Count(), sizeof(GPUBVH)); |
| 723 | desc.InitData = bvhData.Get(); |
| 724 | if (gpu.BVHBuffer->Init(desc)) |
| 725 | return gpu; |
| 726 | } |
| 727 | |
| 728 | // Upload vertex buffer |
| 729 | { |
| 730 | const Mesh& mesh = _meshes[0]; |
| 731 | gpu.VertexBuffer = GPUBuffer::New(); |
| 732 | auto desc = GPUBufferDescription::Raw(mesh.Vertices * sizeof(Float3), GPUBufferFlags::ShaderResource); |
| 733 | desc.InitData = mesh.VertexBuffer.Get(); |
| 734 | if (gpu.VertexBuffer->Init(desc)) |
| 735 | return gpu; |
| 736 | } |
| 737 | |
| 738 | // Upload index buffer |
| 739 | { |
| 740 | const Mesh& mesh = _meshes[0]; |
| 741 | gpu.IndexBuffer = GPUBuffer::New(); |
| 742 | auto desc = GPUBufferDescription::Raw(mesh.Indices * sizeof(uint32), GPUBufferFlags::ShaderResource); |
| 743 | desc.InitData = mesh.IndexBuffer.Get(); |
| 744 | gpu.IndexBuffer->Init(desc); |