public unsafe BottomLevelAccelerationStructure(Api api, RayTracingProperties rayTracingProperties, BottomLevelGeometry geometries) : base(api, rayTracingProperties) { _geometry = GC.AllocateArray <AccelerationStructureGeometryKHR>(geometries.Geometry.Count, true); geometries.Geometry.CopyTo(_geometry); _buildOffsetInfo = GC.AllocateArray <AccelerationStructureBuildRangeInfoKHR>(geometries.BuildOffsetInfo.Count, true); geometries.BuildOffsetInfo.CopyTo(_buildOffsetInfo); _buildGeometryInfo.SType = StructureType.AccelerationStructureBuildGeometryInfoKhr; _buildGeometryInfo.Flags = _flags; _buildGeometryInfo.GeometryCount = (uint)_geometry.Length; _buildGeometryInfo.PGeometries = (AccelerationStructureGeometryKHR *)Unsafe.AsPointer(ref _geometry[0]); _buildGeometryInfo.Mode = BuildAccelerationStructureModeKHR.BuildAccelerationStructureModeBuildKhr; _buildGeometryInfo.Type = AccelerationStructureTypeKHR.AccelerationStructureTypeBottomLevelKhr; _buildGeometryInfo.SrcAccelerationStructure = default; // Note: Could use stackalloc here, but the model count might be too high uint[] maxPrimCount = new uint[_buildOffsetInfo.Length]; for (int i = 0; i != maxPrimCount.Length; i++) maxPrimCount[i] = _buildOffsetInfo[i].PrimitiveCount; fixed(uint *maxPrimCountPtr = &maxPrimCount[0]) GetBuildSizes(maxPrimCountPtr, out _buildSizesInfo); }
public unsafe TopLevelAccelerationStructure(Api api, RayTracingProperties rayTracingProperties, ulong instanceAddress, uint instancesCount) : base(api, rayTracingProperties) { _instancesCount = instancesCount; // Create VkAccelerationStructureGeometryInstancesDataKHR. This wraps a device pointer to the above uploaded instances. var instancesVk = new AccelerationStructureGeometryInstancesDataKHR(); instancesVk.SType = StructureType.AccelerationStructureGeometryInstancesDataKhr; instancesVk.ArrayOfPointers = new Silk.NET.Core.Bool32(false); instancesVk.Data.DeviceAddress = instanceAddress; // Put the above into a VkAccelerationStructureGeometryKHR. We need to put the // instances struct in a union and label it as instance data. _topASGeometry.Value.SType = StructureType.AccelerationStructureGeometryKhr; _topASGeometry.Value.GeometryType = GeometryTypeKHR.GeometryTypeInstancesKhr; _topASGeometry.Value.Geometry.Instances = instancesVk; _buildGeometryInfo.SType = StructureType.AccelerationStructureBuildGeometryInfoKhr; _buildGeometryInfo.Flags = _flags; _buildGeometryInfo.GeometryCount = 1; _buildGeometryInfo.PGeometries = _topASGeometry.Ptr; _buildGeometryInfo.Mode = BuildAccelerationStructureModeKHR.BuildAccelerationStructureModeBuildKhr; _buildGeometryInfo.Type = AccelerationStructureTypeKHR.AccelerationStructureTypeTopLevelKhr; _buildGeometryInfo.SrcAccelerationStructure = default; GetBuildSizes(&instancesCount, out _buildSizesInfo); }
public unsafe ShaderBindingTable( Api api, RayTracingPipeline rayTracingPipeline, RayTracingProperties rayTracingProperties, List <Entry> rayGenPrograms, List <Entry> missPrograms, List <Entry> hitGroups) { RayGenEntrySize = GetEntrySize(rayTracingProperties, rayGenPrograms); MissEntrySize = GetEntrySize(rayTracingProperties, missPrograms); HitGroupEntrySize = GetEntrySize(rayTracingProperties, hitGroups); RayGenOffset = 0; MissOffset = (ulong)rayGenPrograms.Count * RayGenEntrySize; HitGroupOffset = MissOffset + (ulong)missPrograms.Count * MissEntrySize; RayGenSize = (ulong)rayGenPrograms.Count * RayGenEntrySize; MissSize = (ulong)missPrograms.Count * MissEntrySize; HitGroupSize = (ulong)hitGroups.Count * HitGroupEntrySize; // Compute the size of the table. ulong sbtSize = (ulong)rayGenPrograms.Count * RayGenEntrySize + (ulong)missPrograms.Count * MissEntrySize + (ulong)hitGroups.Count * HitGroupEntrySize; // Allocate buffer & memory. _buffer = new Buffer(api, sbtSize, BufferUsageFlags.BufferUsageShaderDeviceAddressBit | BufferUsageFlags.BufferUsageTransferSrcBit); _bufferMemory = _buffer.AllocateMemory(MemoryAllocateFlags.MemoryAllocateDeviceAddressBit, MemoryPropertyFlags.MemoryPropertyHostVisibleBit); // Generate the table. uint handleSize = rayTracingProperties.ShaderGroupHandleSize; ulong groupCount = (ulong)rayGenPrograms.Count + (ulong)missPrograms.Count + (ulong)hitGroups.Count; byte[] shaderHandleStorage = new byte[groupCount * handleSize]; fixed(byte *shaderHandleStoragePtr = &shaderHandleStorage[0]) { Util.Verify(api.KhrRayTracingPipeline.GetRayTracingShaderGroupHandles( api.Device.VkDevice, rayTracingPipeline.VkPipeline, 0, (uint)groupCount, (nuint)shaderHandleStorage.Length, shaderHandleStoragePtr ), $"{nameof(ShaderBindingTable)}: Unable to get ray tracing shader group handles"); // Copy the shader identifiers followed by their resource pointers or root constants: // first the ray generation, then the miss shaders, and finally the set of hit groups. byte *pData = (byte *)_bufferMemory.Map(0, sbtSize); pData += CopyShaderData(pData, rayTracingProperties, rayGenPrograms, RayGenEntrySize, shaderHandleStoragePtr); pData += CopyShaderData(pData, rayTracingProperties, missPrograms, MissEntrySize, shaderHandleStoragePtr); CopyShaderData(pData, rayTracingProperties, hitGroups, HitGroupEntrySize, shaderHandleStoragePtr); } _bufferMemory.Unmap(); }
public unsafe VulkanRenderer(UserSettings userSettings, Window window, IScene scene, CameraInitialState cameraInitialState, ILogger logger, bool enableDebugLogging) { _userSettings = userSettings; _window = window; _api = new Api(enableDebugLogging, logger); _presentMode = _userSettings.VSync ? PresentModeKHR.PresentModeFifoKhr : PresentModeKHR.PresentModeImmediateKhr; _api.Instance = new Instance(_api, _window, new Version32(1, 2, 0)); _surface = new Surface(_api, _window, _api.Instance); // Find the vulkan device we want var physicalDevice = _api.Instance.PhysicalDevices.Where(d => { _api.Vk.GetPhysicalDeviceFeatures(d, out var deviceFeatures); if (deviceFeatures.GeometryShader == false) { return(false); } var queueFamilies = Enumerate.Get <PhysicalDevice, QueueFamilyProperties>(d, (device, count, values) => _api.Vk.GetPhysicalDeviceQueueFamilyProperties(device, (uint *)count, (QueueFamilyProperties *)values)); for (var i = 0; i < queueFamilies.Count; i++) { if (queueFamilies[i].QueueCount > 0 && queueFamilies[i].QueueFlags.HasFlag(QueueFlags.QueueGraphicsBit)) { return(true); } } return(false); }).FirstOrDefault(); if (physicalDevice.Handle == 0) { throw new Exception($"{nameof(VulkanRenderer)}: Could not find a suitable graphics device."); } var deviceProps = new PhysicalDeviceProperties2(); deviceProps.SType = StructureType.PhysicalDeviceProperties2; _api.Vk.GetPhysicalDeviceProperties2(physicalDevice, &deviceProps); _api.Logger.Debug($"{nameof(VulkanRenderer)}: Setting physical device: {deviceProps.Properties.DeviceID} ({Marshal.PtrToStringAnsi((nint)deviceProps.Properties.DeviceName)})"); // Opt-in into mandatory device features. var shaderClockFeatures = new PhysicalDeviceShaderClockFeaturesKHR(); shaderClockFeatures.SType = StructureType.PhysicalDeviceShaderClockFeaturesKhr; shaderClockFeatures.PNext = null; shaderClockFeatures.ShaderSubgroupClock = true; var deviceFeatures = new PhysicalDeviceFeatures(); deviceFeatures.FillModeNonSolid = true; deviceFeatures.SamplerAnisotropy = true; deviceFeatures.ShaderInt64 = true; // Required device features. var bufferDeviceAddressFeatures = new PhysicalDeviceBufferDeviceAddressFeatures(); bufferDeviceAddressFeatures.SType = StructureType.PhysicalDeviceBufferDeviceAddressFeatures; bufferDeviceAddressFeatures.PNext = &shaderClockFeatures; bufferDeviceAddressFeatures.BufferDeviceAddress = true; var indexingFeatures = new PhysicalDeviceDescriptorIndexingFeatures(); indexingFeatures.SType = StructureType.PhysicalDeviceDescriptorIndexingFeatures; indexingFeatures.PNext = &bufferDeviceAddressFeatures; indexingFeatures.RuntimeDescriptorArray = true; indexingFeatures.ShaderSampledImageArrayNonUniformIndexing = true; var accelerationStructureFeatures = new PhysicalDeviceAccelerationStructureFeaturesKHR(); accelerationStructureFeatures.SType = StructureType.PhysicalDeviceAccelerationStructureFeaturesKhr; accelerationStructureFeatures.PNext = &indexingFeatures; accelerationStructureFeatures.AccelerationStructure = true; var rayTracingFeatures = new PhysicalDeviceRayTracingPipelineFeaturesKHR(); rayTracingFeatures.SType = StructureType.PhysicalDeviceRayTracingPipelineFeaturesKhr; rayTracingFeatures.PNext = &accelerationStructureFeatures; rayTracingFeatures.RayTracingPipeline = true; _api.Device = new Device(_api, physicalDevice, _surface, deviceFeatures, Unsafe.AsPointer(ref rayTracingFeatures)); // Now that we have an instance and a device, load all of the extentions we need. _api.InitializeExtensions(); _commandPool = new CommandPool(_api, _api.Device.GraphicsFamilyIndex, true); _rayTracingProperties = new RayTracingProperties(_api); // Load the scene, and create the swap chain / command buffers LoadScene(scene, cameraInitialState); _currentFrame = 0; _api.Device.WaitIdle(); }
protected AccelerationStructure(Api api, RayTracingProperties rayTracingProperties) => (_api, _rayTracingProperties, _flags) =