private void CreateAccelerationStructure() { vertexBuffers = new ID3D12Resource[2]; vertexBuffers[0] = CreateTriangle(device); vertexBuffers[1] = CreatePlane(device); var vertexCounts = new int[2]; vertexCounts[0] = 3; vertexCounts[1] = 6; AccelerationStructureBuffers[] bottomLevelBuffers = new AccelerationStructureBuffers[2]; bottomLevelBuffers[0] = CreateBottomLevelAS(device, commandList, vertexBuffers, vertexCounts, 2); bottomLevelBuffers[1] = CreateBottomLevelAS(device, commandList, vertexBuffers, vertexCounts, 1); bottomLevelAS = new ID3D12Resource[2]; bottomLevelAS[0] = bottomLevelBuffers[0].Result; bottomLevelAS[1] = bottomLevelBuffers[1].Result; CreateTopLevelAS(device, commandList, bottomLevelAS, ref tlasSize, false, 0); SubmitCommandList(); fence.SetEventOnCompletion(fenceValue, fenceEvent); fenceEvent.WaitOne(); var bufferIndex = swapChain.GetCurrentBackBufferIndex(); commandList.Reset(frameObjects[0].cmdAllocator, null); topLevelAS = buffers.Result; }
private AccelerationStructureBuffers CreateBottomLevelAS(ID3D12Device5 device, ID3D12GraphicsCommandList4 commandList, ID3D12Resource[] vertexBuffers, int[] vertexCounts, int geometryCount) { RaytracingGeometryDescription[] descs = new RaytracingGeometryDescription[geometryCount]; for (int i = 0; i < descs.Length; i++) { descs[i] = new RaytracingGeometryDescription(); descs[i].Type = RaytracingGeometryType.Triangles; descs[i].Triangles = new RaytracingGeometryTrianglesDescription(); descs[i].Triangles.VertexBuffer = new GpuVirtualAddressAndStride(); descs[i].Triangles.VertexBuffer.StartAddress = vertexBuffers[i].GPUVirtualAddress; descs[i].Triangles.VertexBuffer.StrideInBytes = 3 * 4; descs[i].Triangles.VertexFormat = Format.R32G32B32_Float; descs[i].Triangles.VertexCount = vertexCounts[i]; descs[i].Flags = RaytracingGeometryFlags.Opaque; } BuildRaytracingAccelerationStructureInputs inputs = new BuildRaytracingAccelerationStructureInputs(); inputs.Layout = ElementsLayout.Array; inputs.Flags = RaytracingAccelerationStructureBuildFlags.None; inputs.DescriptorsCount = geometryCount; inputs.GeometryDescriptions = descs; inputs.Type = RaytracingAccelerationStructureType.BottomLevel; RaytracingAccelerationStructurePrebuildInfo info = device.GetRaytracingAccelerationStructurePrebuildInfo(inputs); HeapProperties properties = new HeapProperties(HeapType.Default, CpuPageProperty.Unknown, MemoryPool.Unknown, 0, 0); AccelerationStructureBuffers buffers = new AccelerationStructureBuffers(); buffers.Scratch = CreateBuffer(device, info.ScratchDataSizeInBytes, ResourceFlags.AllowUnorderedAccess, ResourceStates.UnorderedAccess, properties); buffers.Result = CreateBuffer(device, info.ResultDataMaxSizeInBytes, ResourceFlags.AllowUnorderedAccess, ResourceStates.RaytracingAccelerationStructure, properties); BuildRaytracingAccelerationStructureDescription asDesc = new BuildRaytracingAccelerationStructureDescription(); asDesc.Inputs = inputs; asDesc.DestinationAccelerationStructureData = buffers.Result.GPUVirtualAddress; asDesc.ScratchAccelerationStructureData = buffers.Scratch.GPUVirtualAddress; commandList.BuildRaytracingAccelerationStructure(asDesc); commandList.ResourceBarrier(ResourceBarrier.BarrierUnorderedAccessView(buffers.Result)); return(buffers); }
private void CreateTopLevelAS(ID3D12Device5 device, ID3D12GraphicsCommandList4 commandList, ID3D12Resource[] bottomLevelAS, ref long tlasSize, bool isUpdate, float rotate) { int instanceCount = 3; BuildRaytracingAccelerationStructureInputs inputs = new BuildRaytracingAccelerationStructureInputs(); inputs.Layout = ElementsLayout.Array; inputs.Flags = RaytracingAccelerationStructureBuildFlags.AllowUpdate; inputs.DescriptorsCount = instanceCount; inputs.Type = RaytracingAccelerationStructureType.TopLevel; var info = device.GetRaytracingAccelerationStructurePrebuildInfo(inputs); if (isUpdate == false) { HeapProperties properties = new HeapProperties(HeapType.Default, CpuPageProperty.Unknown, MemoryPool.Unknown, 0, 0); HeapProperties upload_properties = new HeapProperties(HeapType.Upload, CpuPageProperty.Unknown, MemoryPool.Unknown, 0, 0); long descSize = (long)Unsafe.SizeOf <MyRaytracingInstanceDescription>(); buffers = new AccelerationStructureBuffers(); buffers.Scratch = CreateBuffer(device, info.ScratchDataSizeInBytes, ResourceFlags.AllowUnorderedAccess, ResourceStates.UnorderedAccess, properties); buffers.Result = CreateBuffer(device, info.ResultDataMaxSizeInBytes, ResourceFlags.AllowUnorderedAccess, ResourceStates.RaytracingAccelerationStructure, properties); buffers.InstanceDesc = CreateBuffer(device, descSize * instanceCount, ResourceFlags.None, ResourceStates.GenericRead, upload_properties); tlasSize = info.ResultDataMaxSizeInBytes; } else { InsertUAVResourceBarrier(buffers.Result); } int instanceContr = 0; MyRaytracingInstanceDescription[] instanceDescs = new MyRaytracingInstanceDescription[instanceCount]; for (int i = 0; i < instanceCount; i++) { instanceDescs[i] = new MyRaytracingInstanceDescription(); float xPos = (i - 1) * 1.5f; float yPos = 0.0f; float zPos = 0.0f; instanceDescs[i].Transform = Matrix4x4.Identity; if (i != 1) { instanceDescs[i].Transform *= Matrix4x4.CreateRotationY(rotate); if (i == 2) { zPos = -0.5f; } } instanceDescs[i].Transform *= Matrix4x4.CreateTranslation(xPos, yPos, zPos); instanceDescs[i].Transform = Matrix4x4.Transpose(instanceDescs[i].Transform); instanceDescs[i].InstanceID = i; instanceDescs[i].InstanceContributionToHitGroupIndex = instanceContr; instanceDescs[i].Flags = (byte)RaytracingInstanceFlags.None; instanceDescs[i].InstanceMask = 0xFF; if (i == 1) { instanceDescs[i].AccelerationStructure = bottomLevelAS[0].GPUVirtualAddress; instanceContr += 4; } else { instanceDescs[i].AccelerationStructure = bottomLevelAS[1].GPUVirtualAddress; instanceContr += 2; } } IntPtr data = buffers.InstanceDesc.Map(0, null); Helpers.CopyMemory <MyRaytracingInstanceDescription>(data, new ReadOnlySpan <MyRaytracingInstanceDescription>( instanceDescs)); buffers.InstanceDesc.Unmap(0, null); BuildRaytracingAccelerationStructureDescription asDesc = new BuildRaytracingAccelerationStructureDescription(); asDesc.Inputs = inputs; asDesc.Inputs.InstanceDescriptions = buffers.InstanceDesc.GPUVirtualAddress; asDesc.DestinationAccelerationStructureData = buffers.Result.GPUVirtualAddress; asDesc.ScratchAccelerationStructureData = buffers.Scratch.GPUVirtualAddress; if (isUpdate) { asDesc.Inputs.Flags |= RaytracingAccelerationStructureBuildFlags.PerformUpdate; asDesc.SourceAccelerationStructureData = buffers.Result.GPUVirtualAddress; } commandList.BuildRaytracingAccelerationStructure(asDesc); InsertUAVResourceBarrier(buffers.Result); }